Текст
                    АЙЗЕКС С.
Dynamic HTML

NO TEXT
NO TEXT
NO TEXT
Введение Всемирная Паутина (World Wide Web) спровоцировала революцию в ин- форматике, предоставив любому пользователю возможность публикации HTML-документов. До недавнего времени информация в этих документах была в большинстве случаев статической, что требовало реакции сервера на действия пользователя. С введением динамического HTML парадигма Web сместилась от взаимодействия с сервером в сторону создания интерактив- ных Web-узлов и Web-приложений. Поскольку динамический HTML обес- печивает возможность взаимодействия HTML-документов с пользователем и полного их изменения на клиентском компьютере, вы можете создавать Web-приложения с богатыми возможностями. Динамический HTML построен на объектной модели, которая расширяет традиционный статический HTML-документ. С помощью данной книги вы изучите динамический HTML и научитесь создавать страницы, которые бу- дут в интерактивном режиме взаимодействовать с пользователем. Материал данной книги предполагает, что читатель знаком с HTML и основными принципами программирования. В книге нет описания HTML или основ программирования на языках JavaScript, JScript или VBScript. Данные языки рассматриваются как инструменты для манипулирования страницами в ди- намическом режиме. В конце введения приведено описание четырех частей книги. Прочтите его, чтобы получить понятие о принципе представления информации о динами- ческом HTML в виде серии блоков. В заключение рассматривается создание интерактивных Web-страниц. Создание интерактивных страниц Концепция создания интерактивных Web-страниц нс является новой — компании Microsoft и Netscape изначально определили простую объектную модель, которая была представлена как способ создания интерактивных страниц. При более внимательном рассмотрении объектная модель оказа- лась более эффективной только для базовой проверки форм. Динамические документы были по большей части мифом до появления Microsoft Internet
6 Введение Explorer 4.0, поскольку страница могла быть изменена только при ее созда- нии. Интерактивные документы моделировались путем полной перезагрузки страницы или внедрения объектов на страницу. Многие апплеты Java, эле- менты управления ActiveX и даже анимированные изображения в формате GIF были разработаны для выполнения операций, аналогичных тексту, что позволяло преодолеть статическую природу HTML. Однако использование объектов вместо стиля и элементов управления содержанием представляет собой не самое лучшее решение. После изучения множества схем для данных объектов и анимированных изображений GIF, разработчики Internet Explorer пришли к выводу, что для манипулирования документами необходим более мощный прикладной ин- терфейс программирования (application programming interface, API). С помо- щью объектной модели, которая обеспечивает полный доступ к документу, Web-мастеры могут использовать встроенные возможности размещения объ- ектов в HTML и каскадные таблицы стилей (Cascading Style Sheets, CSS). Такая модель существенно улучшает производительность, сокращая необхо- димость загрузки больших анимированных изображений GIF и апплетов. Информация становится доступной мгновенно, поскольку она больше не спрятана внутри изображений или объектов. Динамический HTML обеспечивает API, необходимый для полного управ- ления HTML-документом. Больше не требуется определять страницу во время загрузки. После загрузки любая часть страницы может быть сразу же изменена в динамическом режиме. Например, вы можете создать приложе- ние, которое разворачивает или сворачивает список содержания документа. Когда пользователь разворачивает или сворачивает список, на экран мгно- венно выводится пли с него удаляется содержание. Представьте создание страниц, которые автоматически изменяются и настраиваются для пользова- теля. Все это возможно с помощью динамического HTML. Способность изменения документа и автоматическое переформатирование документа является основным нововведением, которое используется в ди- намическом HTML. Традиционные браузеры были основаны на инструмен- тах перехода по документу, которые отображали документ и затем ожидали, пока пользователь выберет новый документ. Когда требовалось внести из- менение в документ, для создания повой страницы отправлялся запрос на сервер, который и генерировгш ее на машине клиента. Языки программирования Язык программирования используется для манипулирования объектной мо- делью динамического HTML, но динамический HTML разработан как неза- висимый от платформы и языка программирования. Поэтому могут быть использованы языки программирования JavaScript, JScript, VBScript, C++, Java, а также другие языки.
Введение 7 В данной книге используется преимущественно язык JScript Для доступа к объектной модели документа. JScript является реализацией компании Mi- crosoft стандарта ЕСМА262 (European Computer Manufacturers Association — европейская ассоциация производителей компьютеров), разработанного компаниями Microsoft, Netscape и другими организациями. Данный стандарт формализует языковые конструкции JavaScript и JScript, так что могут быть созданы реализации, допускающие совместное взаимодействие. Важно пом- нить, что данный стандарт определяет только конструкции языка. Несмотря на то, что язык часто ассоциируется с объектной моделью, данный стандарт не определяет объектную модель. Поэтому, когда вы определяете, поддер- живает ли браузер версию JavaScript или JScript, следует четко различать объектную модель и элемент языка. JScript в Internet Explorer 4.0 совместим со стандартом ЕСМА, но реализация JavaScript 1.2 в Netscape 4.0 с ним не совместима. ( Примечание j Термины JavaScript и JScript могут быть в общем случае использованы как си- нонимы при обсуждении языков программирования. В данной книге использу- ется JavaScript, поскольку он более широко известен. Апплеты и объекты на странице могут взаимодействовать с ней. Например, в Internet Explorer объект, написанный на C++ или другом языке, реализует взаимодействие со страницей посредством объектной модели. Описание ме- тода создания апплетов, использующих динамический HTML, выходит за рамки этой книги. Однако данная книга содержит основы для понимания возможностей взаимодействия динамического HTML с такими объектами. Если вы знакомы с языком JavaScript и существующей объектной моделью, то обнаружите, что расширения объектной модели динамического HTML совместимы со всеми предыдущими версиями. Все страницы, написанные для предыдущих версий Internet Explorer или Netscape Navigator 3.0, будут выполняться в Internet Explorer 4.0. Такая совместимость позволяет Web- мастерам использовать имеющиеся знания при изучении данных нововведе- ний. Тем, кто не знаком с JavaScript, изучение методов программирования HTML-страницы позволит расширить и улучшить работу создаваемых стра- ниц и приобрести некоторый опыт. Новые элементы Динамический HTML снимает все ограничения на доступ к документу. Ди- намический HTML в Internet Explorer 4.0 предоставляет в распоряжение разработчиков ряд новых элементов, которые обсуждаются в следующих разделах.
в Введение □ HTML 4.0 и расширенная поддержка CSS. Браузер Internet Explorer 4.0 поддерживает последний стандарт HTML 4.0, CSSI и множество новых элементов в CSS. Эти стандарты HTML и CSS определяют элементы, представляемые объектной моделью динамического HTML. □ Полный доступ к структуре документа. Доступ к элементам в документе поддерживается объектной моделью динамического HTML. Вы больше не ограничены программированием элементов форм. Стиль и содержание любого элемента могут быть изменены в динамическом режиме, и дан- ные изменения будут немедленно отражены в документе. Кроме того, улучшены внутренние элементы управления для поддержки HTML и CSS, что позволяет Web-мастеру манипулировать внешним ви- дом данных элементов управления, включая установку цвета текста, фона и шрифта на кнопках и текстовых элементах управления. Объектная мо- дель внутренних элементов управления сходна с объектной моделью до- кумента и обеспечивает простой доступ к стилю и содержанию. □ Динамический стиль. Таблицы стилей CSS документа могут быть измене- ны в любое время. Документ не требуется перезагружать из кэша или об- ращаться на сервер. Объектная модель разработана для предоставления возможности немедленного отображения любых изменений на странице. Например, внешний вид элемента может быть изменен при перемеще- нии указателя мыши или нажатии кнопки мыши на элементе. □ Динамическое содержание. Объектная модель позволяет обращаться к со- держимому документа и изменять его. Кроме того, при этом не требуется взаимодействие с сервером и реакция будет мгновенной. Например, можно написать утилиту электронных часов в стандартном HTML. Больше не требуется использовать апплеты Java или элементы управле- ния ActiveX для изменения содержания. □ Мгновенный ответ пользователя. Динамический HTML предоставляез мощную новую модель событий, которая представляет все пользователь- ские действия на странице. Сценарии в документе могут реагировать на все действия пользователя внутри браузера. На основе действий пользо- вателя любой апплет в содержании документа или стиле может быть из- менен в динамическом режиме. □ Web-страницы клиент/сервер. Internet Explorer 4.0 добавляет расширения в HTML-элементы для создания таблиц со связыванием данных и форм с одиночной записью и отчетов. Данные асинхронно загружаются и вос- производятся в документе, используя несколько базовых HTML- расширении. Данные могут быть кэшированы локально, позволяя осуще- ствлять поиск и сортировку на клиентской стороне без помощи сервера. ' Например, поисковые машины могут представлять множество результа- тов поиска одновременно. Напротив, поисковая машина может отправ- лять запросы клиенту, где они будут воспроизводиться по мере получе-
Введение 9 ния. Пользователь может мгновенно сортировать и отбирать данные пол- ностью на локальной машине, не отправляя запросов на сервер. □ Эффекты мультимедиа и анимации. Браузер Internet Explorer 4.0 тесно ин- тегрирует эффекты мультимедиа и анимации с содержанием документа. Данные эффекты включают фильтры, которые могут моделировать ис- точники света, тени и другие эффекты, которые реализуются непосредст- венно в тексте или других элементах управления. Могут быть также до- бавлены эффекты перехода между изображениями и текстом, и даже ме- жду страницами. Все эти элементы основаны на текущем обсуждении внутри рабочих групп консорциума W3C (World Wide Web Consortium). Объектная модель динами- ческого HTML рассматривается рабочей группой объектной модели докумен- та (Document Object Model). Цель этой группы заключается в определении объектной модели, которая является независимой от языка и платформы и удовлетворяет ряду требований для структурированных документов. Объект- ная модель, которая определена в Internet Explorer 4.0, удовлетворяет всем требованиям, изложенным рабочей группой объектной модели документа. / Определение HTML-документа HTML является приложением языка SGML (Standard Generalized Markup Language — стандартный обобщенный язык разметки). В документе HTML/SGML теги определяют структуру содержания документа. Традици- онный SGML-документ имеет три различных компонента: структура, стиль и содержание. С введением динамического HTML был добавлен четвертый компонент: модель поведения. Термин модель поведения (behavior) определя- ет взаимодействие между пользователем и HTML-страницей. Основное внимание в данной книге сосредоточено на создании HTML-приложений путем манипулирования различными компонентами документа. Структура представлена рядом семейств элементов; стиль представлен для каждого элемента и во всех семействах таблиц стилей. Содержание представлено по- средством всех элементов и объекта TextRange. Сценарии (скрипты) манипу- лируют структурой, стилем и содержанием в ответ на события для создания модели поведения документа. Структура и стиль Структура обеспечивает контекст для информации, которая содержится внутри документа. Например, элементы Header с Н1 по нб предназначены для определения различных заголовков и их относительного значения. По- сле элемента н1 может находиться другой элемент Н1 или элемент Н2, по не элемент нз. Однако HTML быстро развивается и разделение между структу- рой и представлением часто игнорируется. Web-мастеры используют теги
10 Введение HTML не для создания структуры, а для определения стиля. Элемент н] часто используется для отображения текста крупным шрифтом полужирного начертания, а не для определения заголовка высшего уровня. По мере даль- нейшего отклонения от SGML были изобретены теги стилей. Например, были введены теги <в> и <1> для выделения текста полужирным начертани- ем и курсивом. При просмотре страницы пользователь (а больше всего ее автор) обычно не заботится о ее структуре. Цель автора заключается в создании интересной страницы, которая бы чаще посещалась пользователями Web. Стремление к оригинальности является причиной создания множества стилистических тегов. Однако нарушение стиля имеет последствия. Первое из них заключается в том, что инструменты становятся менее мощными. Если автор корректно использует структуру, то инструмент индексирования сможет правильно ин- дексировать содержание документа. Если тег <strong> используется для обо- значения значимости слова, то инструмент индексирования может назна- чить слову больший вес. Однако многие авторы используют тег <strong> просто для отображения слова полужирным начертанием, вместо подчерки- вания значения слова, лишая данный тег его значения. Более важной причиной необходимости правильного структурирования стра- ницы является повышение доступности основной информации. Представь- те, что браузер читает информацию вслух вместо ее визуального отображе- ния. Например, браузер для слепых или голосовой браузер для автомобиля. Такие браузеры должны иметь возможность воспроизведения различных особенностей текста. Выделенные слова должны быть произнесены с ударе- нием, и заголовки должны соответствовать списку содержания на странице. Если документ использует разметку только в целях представления, то голо- совой браузер не сможет правильно воспроизвести содержание документа. HTML также определяет набор правил, представляющих правильную струк- туру документа. Определение типа документа (document definition type, DTD) описывает, какие элементы могут находиться внутри других элементов. Важно понимать, что элементы HTML не могут располагаться в любом мес- те документа. Обычно плохое воспроизведение Web-страннцы в браузере обусловлено несоответствием элементов HTML определению DTD. К сожа- лению, многие страницы в Web не соответствуют DTD, а вместо того, чтобы заставить пользователей создавать корректные документы, для браузеров был разработан упрощенный набор правил для анализа документа, которые пытаются интерпретировать замысел автора, часто не самым лучшим образом. До середины 60-х годов стиль в HTML контролировался достаточно просто, путем использования тегов и атрибутов стиля, таких как align. В этих усло- виях HTML не являлся действительным языком SGML, в котором структура и стиль определены раздельно. В действительном языке SGML документ
Введение 11 может иметь связанную с ним таблицу стиля, которая определяет воспроиз- ведение структурных элементов. В середине 60-х был введен новый язык SGML — каскадные таблицы стилей (Cascading Style Sheets) для определения стиля в HTML. Спецификация CSS была разработана с участием Берт Хос и Хскеп Лыо из консорциума W3C, а также с участием многих других членов W3C и была принята большинством браузеров. По существу, элементы strong в CSS (и лаже элемент Bold в дан- ном случае) больше не служат для выделения текста полужирным начерта- нием. Вместо этого элемент strong используется традиционным образом для выделения важного слова. Таблица стилей теперь определяет, что элемент strong должен быть выделен полужирным начертанием: STRONG {font-weight:bold) Для полноценного использования возможностей динамического HTML до- кумент должен правильно отделять содержание и структуру от представле- ния. Динамический HTML проще использовать и он работает более пред- сказуемо с действительными HTML-документами. И как будет показано в этой книге, манипулирование недействительным HTML сложнее и может привести к непредсказуемым результатам. Структура книги Изучения программирования интерактивных страниц представляет собой по- степенный процесс. Данная книга начинается с изложения основных концеп- ций, затем рассматривается применение этих концепций для обучения мето- дам обращения к различным компонентам браузера и документа. Книга со- стоит из четырех частей, краткое описание которых приведено ниже. Часть I. HTML и программирование сценариев В главах с 1 по 5 рассматриваются отношения между программированием сценариев и HTML-документом, описывается окно браузера и объясняется использование модели событий динамического HTML. Предполагается, что читатель знаком с основами HTML и программирования на языках JavaScript или VBScript. В части 1 вводится понятие иерархии объектов, которая представляет четыре компонента документа: структуру, стиль, содержание и модель поведения. Компоненты подробно обсуждаются в частях П—IV, а поскольку данные вопросы тесно связаны, многие объяснения частично повторяются. Часть II. Структура документа В динамическом HTML все элементы и их атрибуты доступны для про- грамм. В части II показано, как обращаться и использовать возможности
12 Введение семейства элементов документа и как манипулировать индивидуальными элементами внутри документа. Здесь же демонстрируется создание интер- активных форм с богатыми возможностями, которые могут обрабатывать информацию на клиентском компьютере без обмена информацией с сер- вером. Часть III. Стиль документа и анимация Основной темой обсуждения в части III является концепция стиля, которая тесно связана с индивидуальными элементами. Используя таблицы стилей, Web-мастер определяет внешний вид документа, пробелы, цветовую гамму и так далее. В этой части также рассмотрено добавление базовых элементов анимации на HTML-страницу. Динамический HTML представляет набор функций-членов, которые позволяют создавать плавающие HTML-элементы, которые можно перемещать по HTML-странице, и создавать простые эффекты презентации. Кроме того, динамический HTML включает набор мощных расширений, ко- торые позволяют добавлять реальные эффекты мультимедиа, анимации и пе- реходов на вашу Web-страницу. С учетом этих улучшений содержание HTML может быть анимировано с использованием лишь нескольких строк кода. Часть IV. Содержание документа и связывание данных В части IV демонстрируется, как с помощью динамического HTML можно установить режим динамического изменения страниц. Содержание пред- ставлено посредством свойств на каждом элементе и посредством модели текстового объекта. С помощью динамического содержания можно легко обращаться к тексту HTML, неформатированному тексту и изменять их. В главе 15 показано, как использовать динамический HTML для создания Web-страниц клиент/сервер, включая связывания HTML-таблицы с набором данных, которым можно манипулировать локально. Данная возможность позволяет создавать быстро загружаемые страницы с данными, которые можно легко сортировать, отбирать и редактировать на стороне клиента. Прилагаемый компакт-диск Прилагаемый к книге компакт-диск содержит примеры кода, приведенные в книге, а также индексную страницу со ссылками на все примеры, что по- зволяет быстро находить требуемые программы. Кроме того, на компакт-диске находится дистрибутив браузера Microsoft Internet Explorer 4.0 и пакета разработчика Microsoft Internet Client Software Development Kit. Документация no SDK включает полное описание динами- ческого HTML, а также другую полезную информацию.
Введение 13 Персональный Web-узел автора книги (www.insideDHTML.com) содержит дополнительную информацию о динамическом HTML. Компания Microsoft поддерживает несколько Web-узлов, которые содержат информацию, свя- занную с динамическим HTML, включая Site Builder (www.microsoft.coni/ sitebuilder) и JScript (www.microsoft.com/JScriDtk Поддержка Были приняты все меры для обеспечения корректности содержания данной книги и прилагаемого компакт-диска. Издательство Microsoft Press публи- кует исправления в издаваемых книгах на своем Wcb-узлс по адресу mspress.microsoft.com/mspress/support/. Если у вас есть комментарии, вопро- сы или идеи относительно этой книги или прилагаемого компакт-диска, вы можете направить их в издательство Microsoft Press по обычной или элек- тронной почте: Microsoft Press Attn: Inside Dynamic HTML Editor One Microsoft Way Redmond, WA 98052-6399 MSPIN PUT@MICROSOFT.COM Обратите внимание, что поддержка продуктов не осуществляется по данным почтовым адресам.

HTML и программирование сценариев Глава 1. Обзор HTML и CSS Глава 2. Основы сценариев HTML Глава 3. Модель событий динамического HTML Глава 4. Окно браузера Глава 5. Управление окном и фреймом

Глава 1 Обзор HTML и CSS HTML (HyperText Markup Language — язык разметки гипертекста) продол- жает развиваться. За последние годы в HTML появились два новых элемен- та: новый язык управления стилем и объектная модель для изменения пове- дения и повышения динамизма объектов. Динамический HTML в Microsoft Internet Explorer 4.0 заключает в себе не только объектную модель для мани- пулирования документом, но также многие последние рекомендации из спецификаций HTML, таблиц каскадных стилей CSS (Cascading Style Sheets) и рабочих проектов консорциума W3C (World Wide Web Consortium). В этой главе рассматриваются некоторые из последних нововведений в HTML и CSS, поддерживаемые Microsoft Internet Explorer 4.0. Комбинация имеющихся возможностей HTML и новых элементов вместе с объектной моделью динамического HTML (Dynamic HTML) позволяют создавать интер- активные Web-страницы и Web-приложения. Данная глава не претендует на полноту описания HTML и CSS — цель заключается в обучении приемам эффективного использования HTML и CSS. Здесь вы познакомитесь с по- следними достижениями в этой области. В главе рассмотрены следующие темы: СЗ Новые элементы HTML. В этом разделе дается описание новых элемен- тов, которые будут включены в следующую версию HTML. Следующая версия HTML (HTML 4.0) разрабатывается членами консорциума W3C. Когда вы будете читать эту книгу, спецификация HTML 4.0 уже, навер- ное, будет принята консорциумом W3C. В данном разделе также рас- сматриваются элементы HTML, поддерживаемые Internet Explorer 4.0, ко- торые выходят за рамки спецификации HTML 4.0. □ Каскадные таблицы стилей (Cascading Style Sheets). Язык SGML (Standard Generalized Markup Language — стандартный обобщенный язык разметки) и соответственно язык HTML предназначены для разделения содержания
18 Часть I. HTML и программирование сценариев (contents) и представления (presentation). Такое разделение было невоз- можно до появления CSS, когда в HTML были введены теги, такие как <в> и <font>, для определения режима вывода содержания документа на экран. Эти теги нарушают основы структурного документа, позволяя внедрить презентацию в содержание. В данном разделе дается вводное описание языка CSS и его связей с современными сценариями. CSS слу- жит для статического добавления стиля в документ, но с помощью рас- ширений объектной модели стиль может динамически изменяться. На- пример, стиль текста может быть изменен в соответствии с параметрами среды пользователя. □ Проверка определения типа документа HTML. HTML является структури- рованным языком с формальным описанием. В данном разделе обсужда- ется значение определения типа документа (document type definition, DTD), которое устанавливает параметры HTML. DTD HTML является SGML-описанием языка HTML. DTD определяет поддерживаемый набор ' элементов и их атрибуты, а также определяет возможность наличия в элементе других элементов. К сожалению, большинство Web-страниц на- рушают определение типа документа HTML. С помощью добавления объектной модели, которая позволяет использовать сценарии для описа- ния всей страницы, большое значение приобретает обеспечение согласо- ванного и разумного поведения страниц путем создания грамотно струк- турированных документов. В данном разделе вы изучите приемы чтения DTD и использования определения типа документа для создания дейст- вительных НТМ L-документов. Новые элементы HTML Internet Explorer 4.0 обеспечивает полную поддержку HTML 4.0 следующей версии HTML, которая реализована как рекомендация W3C. В данном раз- деле представлены элементы, которые были недавно введены в HTML, 4.0. (Некоторые данные элементы были доступны в Internet Explorer 3.0, но они только теперь включены в рекомендацию W3C.) На момент написания книги в HTML 4.0 были добавлены перечисленные ниже новые элементы: □ Элементы Frameset И IFrame □ Изменения в формах и облегчение доступа □ Изменения в таблицах, которые касаются заголовков, примечаний и столбцов □ Элемент object для внедрения индивидуальных объектов □ Элемент Script для внедрения сценариев (скриптов) □ Возможности загрузки файлов с целью отправки на сервер □ Улучшенный набор именованных компонентов
Глава 1. Обзор HTML и CSS 19 Элементы Frameset и iFrame, изменения в таблицах и элементы object и script поддерживаются, начиная с Internet Explorer 3.0. Internet Explorer 4.0 расширяет их использование, предоставляя поддержку для остальных эле- ментов в данном списке. Информацию об HTML 4.0 и перечисленных эле- ментах можно найти на узле консорциума W3C по адресу www.w3.org и на Web-узле компании Microsoft по адресу www.microsoft.com. Написание сце- нариев для новых элементов и их атрибутов обсуждается на протяжении всей книги. Далее приводится описание синтаксиса HTML для элемента object, улуч- шений в формах и доступе и некоторых новых элементов HTML, которые поддерживаются в Internet Explorer 4.0, но выходят за рамки спецификации HTML 4.0. В главе 2 рассматривается элемент Script, который является главным механизмом вне- дрения сценариев в документ. Описание элементов Frameset приведено в главе 5. В данной книге изменения в таблицах обсуждаются кратко. В число этих изменений входит определение заголовков таблицы, примечаний и тела таб- лицы, а также большие возможности управления столбцами. Более подроб- ную информацию об изменениях в таблицах можно найти па Web-узле ком- пании Microsoft. Именованные компоненты состоят из стандартных символов, которые могут быть внедрены в документ с помощью элемента &name;. Например, широко используемым именованным компонентом является неразрываемый пробел (inbsp), который помещает пробел, не разрываемый в конце строки в доку- менте. Внедрение индивидуальных объектов Элемент object используется для внедрения индивидуальных объектов в до- кумент HTML. Данный элемент изначально поддерживался в Internet Explorer 3.0. Элемент object используется для расширения HTML путем внедрения апплетов Java, элементов управления ActiveX и поддерживаемых в Internet Explorer типов MIME. Поддерживаемые тины MIME включают файлы HTML и различные форматы изображений, такие как GIF, JPEG и PNG. Ниже приведен обычный синтаксис элемента object: <Object CLASSID= ’’ActiveX U'JID” WIDTH= "pixels" HEIGHT= "pixels"> <PARAM NAME= "property" VALUE= "propertyValue"> </OBJECT> Помимо определения значения тега classid мржет быть установлено значе- ние необязательного параметра codebase с целью указания адреса, с кото- рого должен быть загружен объект. Параметры могут быть определены по-
20 Часть I. HTML и программирование сценариев средством одного или нескольких элементов Param, находящихся внутри элемента object. Единственным действительным содержанием в элементе object являются элементы Param. Браузеры, которые поддерживают элемент object, игнори- руют все остальные теги HTML в блоке object. Данный элемент может быть использован для работы с примитивными браузерами, которые не поддер- живают элемент object, как показано ниже: <OBJECT CODE= "myClass.class" WIDTH=200 HEIGHT=200> <PARAM NAME- "color” VALUE- "red"> <PARAM NAME--- "background" VALUE- "green"> <P> Ваш браузер не поддерживает элемент Object и не может быть использован для просмотра приложения. (Your browser does not support the Object element and cannot view the application)</P> </OBJECT> Изменения в формах и облегчение доступа Функция форм HTML первоначально заключалась в запросе базовой ин- формации от пользователя. Интерфейс был ограничен контейнерами про- стого текста, кнопками-переключателями и флажками. Эволюция форм в HTML направлена в сторону увеличения функциональных возможностей и гибкости по сравнению с возможностями, которые предоставляют сущест- вующие пакеты форм и баз данных. Кроме того, многие улучшения, связан- ные с формами, также облегчают доступ, что расширяет возможности про- смотра страниц дня пользователей, вооруженных устаревшими версиями браузеров. ( Примечание ) В данной книге термин внутренние элементы управления (intrinsic elements) используется для обозначения встроенных элементов управления HTML Внут- ренние элементы управления включают в себя все элементы, такие как изо- бражение. текст, кнопка и элементы бегущей строки, с которыми непосредст- венно взаимодействует пользователь при вводе и выводе данных. Улучшения в формах в HTML 4.0 позволяют добавлять надписи и клавиши доступа, поясняющий текст к элементам, управлять последовательностью переходов, отключать элементы управления и группировать связанные эле- менты управления. Кроме того, Internet Explorer 4.0 улучшает внутренние элементы форм посредством поддержки таблиц стилей, кнопки по умолча- нию и кнопки отмены. Кнопки и текстовые окна могут быть созданы с ис- пользованием различных шрифтов и цветов на основе таблиц стилей. Использование таблиц стилей вводится в разделе "Каскадные таблицы стилей" ниже в данной главе.
Глава 1. Обзор HTML и CSS 21 Добавление надписей и клавиш доступа Новый элемент Label представляет собой текстовый контейнер, связываю- щий текстовое содержание с определенным элементом управления. Надписи для элементов управления представляют собой то же, что и ссылки для за- кладок: так же как ссылки открывают закладки, так и щелчок кнопкой мы- ши по надписи отображает связанный элемент управления. Для переключа- телей и флажков щелчок по надписи также приводит к нажатию связанной кнопки и изменению ее значения. Так же, как и тег <а>, который определяет ссылки на закладки, тег <]лвеь> ссылается на связанный элемент управления, используя атрибут for. Атри- бут for содержит уникальный идентификатор (ID) элемента управления на странице. Приведенный ниже код создает надписи для флажка и текстового окна: <нтмь> <HEAD> <TITLE>Label Demonstration</TITLE> </HEAD> <BODY> <Hl>Label Demonstration</Hl> <TABLE> <TR> <TD NOWRAP> CLABEL FOR="Info">Send Information: </LABEL>. </TD> <TD> CINPUT TYPE="CHECKBOX” ID="Info" VALUE-"Information"> </TD> </TR> CTR> CTD NOWRAP> CLABEL FOR="Email">E-Mail Address: </LABEL> </TD> CTD> CINPUT ID="Email" TYPE="Text" SIZE=30> c/TD> c/TR> c/TABLE> c/BODY> </HTML> На рис. 1.1 показано, как при установке флажка вокруг надписи отобража- ется пунктирная рамка. Для установки флажка можно также щелкнуть по самой надписи.
22 Часть I. HTML и программирование сценариев Рис. 1.1. Web-страница Label Demonstration Элемент Label позволяет связывать содержание с элементом управления. Для упрощения доступа к элементу Label в HTML 4.0 имеется атрибут accesskey. Атрибут accesskey содержит одиночный символ, который может быть использован как ярлык для ссылки на элемент управления: нажатие клавиши <Alt> в сочетании с клавишей доступа позволяет обратиться к яр- лыку. (Клавиша доступа не чувствительна к регистру.) Ниже приведен код HTML для создания надписи с клавишей доступа: <!— Label with an access key -- > <LABEL FOR= "txtl" ACCESSKEY= "U" > <SPAN CLASS="accesskey">U</SPAN>ser Name: </LABEL> <INPUT TYPE="Text" SIZE=30 ID=user> Назначение тега <span> в данном примере заключается в использовании глобального стиля, который определяет воспроизведение клавиши доступа в тексте надписи. Microsoft Windows традиционно подчеркивает клавиши дос- тупа. Это может быть выполнено в HTML путем добавления следующего глобального стиля и помещения клавиши доступа в текст надписи с тегами <span>: <STYLE TYPE="text/css"> .accesskey {text-decoration: underline}' </STYLE> Элемент и может быть использован как альтернатива глобального стиля щтя активизации подчеркивания. Однако этот метод не обеспечивает преиму- ществ таблиц стилей. Использование глобального стиля упрощает измене- ние внешнего вида всех клавиш доступа в документе. Надписи ухудшаются постепенно в браузерах низкого уровня, которые не поддерживают надписи. Тег <label> игнорируется примитивными браузера- ми, поэтому надпись обрабатывается как простой текст. (Браузеры, пони- мающие таблицы стилей, подчеркивают букву клавиши доступа). Элемент
Глава 1. Обзор HTML и CSS 23 label существенно улучшает возможности использования и доступа, и ре- комендован для применения с элементами управления. Добавление поясняющего текста в элемент Все элементы HTML теперь поддерживают атрибут title, служащий для определения поясняющей строки, которая воспроизводится в Internet Explorer 4.0 как всплывающая подсказка (ToolTip). Всплывающая подсказка представляет собой небольшое текстовое окно, которое отображается при подведении указателя мыши к элементу. Всплывающая подсказка может быть связана с любым элементом от элемента управления до заголовка. До- бавление атрибута title к созданному ранее флажку приводит к отображе- нию всплывающей подсказки при подведении указателя мыши к данному элементу: <INPUT TYPE= CHECKBOX ID= ’’Info" VALUE= "Information” TITLE= "Check here and enter your user name for more information."> На рис. 1.2 показана всплывающая подсказка на Web-странице ToolTip Demonstration (Демонстрация подсказки). ToolTip Demonstration - Microsoft Internet Explore! HI>1E3 ToolTip Demonstration Send Information: Г. E-Mail Address. |"~ ж I Check here and enter your user name for more information. | ) , J) i-L СогтгрчГрг ' - 0Й Рис. 1.2. Web-страница, демонстрирующая работу всплывающей подсказки При использовании тега <label> атрибут title не создает проблем для при- митивных браузеров, так как они просто игнорируют данный атрибут. По- этому его использование рекомендовано, когда необходим вывод на экран дополнительной информации. Наиболее часто атрибут title используется для вывода дополнительной информации о ссылках и о содержании элемен- та управления. Управление последовательностью перехода Атрибут tabindex был добавлен в HTML 4.0 во все внутренние элементы управления в документе. Данный атрибут позволяет Web-мастеру явно опре- делять последовательность перехода (tabbing order). По умолчанию последо-
гл Часть I. HTML и программирование сценариев вательность перехода между элементами на странице соответствует последо- вательности, в которой элементы определены в источнике HTML. Атрибут tabindex позволяет автору управлять последовательностью перехода фокуса между элементами независимо от последовательности в исходном докумен- те. Установка отрицательного значения атрибута tabindex в элементе позво- ляет пропустить элемент в последовательности перехода. В то время как элементы внутри формы принадлежат форме, атрибут tabindex применяется ко всему документу. Поэтому индекс перехода должен быть указан только для одного элемента в документе. Исходная последова- тельность решает все конфликты, в которых многочисленные элементы, со- вместно используют одинаковое значение индекса перехода. Отключение элементов управления Отключенными элементами управления (disabled controls) называются элемен- ты, которые не могут быть активизированы или содержание которых не мо- жет быть изменено. В HTML 4.0 используются два атрибута для запрета редактирования элемента: readonly и disabled. Атрибут disabled лишает элемент возможности получения фокуса и участия в событиях. Атрибут disabled должен быть использован, когда элемент не применим к текущему контексту. Так, если для получения возможности использования элемента должна быть введена определенная информация, то данный элемент управ- ления может быть отключен до ввода требуемой информации. Для отключе- ния элемента используйте следующий код: <! — Disabled Control -- > CINPUT TYPE= SUBMIT ID= "btnSubmit" VALUE= "Submit Data" DISABLED> После ввода необходимой информации кнопка Submit Data может быть активизирована с помощью сценария. Примеры динамического манипулирования элементами форм с по- мощью объектной модели приведены в главе 10. Атрибут readonly используется, когда элемент применим к контексту, но установлен запрет на редактирование содержания элемента управления. В отличие от отключенного элемента управления элемент управления только для чтения (read-only control) может получить фокус, и его содержание мо- жет быть выделено. Однако содержание данного элемента нельзя изменять. Атрибут readonly применим только к тем элементам, в которых пользова- тель может вводить данные. Например, элементы Button недоступны для редактирования, поэтому использование атрибута readonly для них не тре- буется. Элемент управления только для чтения не отличается от доступного для ре- дактирования элемента управления. ОтключаГный элемент в Windows ото- бражается серым цветом. Приведенный ниже программный код демонстри- рует отключение поля E-Mail Address на рис. 1.1.
Гпава 1. Обзор HTML и CSS 25 <INPUT ID="Email" TYPE="Text” SIZE=30 VALUE="UserName@com" TITLE="To enter an e-mail address, first check the Send Informa- tion check box (Для ввода адреса электронной почты сначала установите флажок Send Information)." DISABLED> На рис. 1.3 показано отключенное текстовое окно. С помощью сценария можно активизировать текстовое окно, когда пользователь устанавливает флажок Send Information. Q Disabled Element Dcmonsliation Miciosoll Internet Disabled Element Demonstration Send Information: Г E-Mail Address: [UsottlenisScom Tо enter an e-mail addiest. first check the Send Information ПМВММЙЙ№Т~ check box. — Рис. 1.3. Web-страница с отключенным элементом Новый элемент Button В HTML 4.0 введен новый элемент Button, который позволяет отображать разнообразные элементы в виде кнопок. Например, приведенный ниже код элемента Button может быть добавлен в пример Label Demonstration: <! —HTML-based button—> <BUTTON STYLE="font-family: Arial; font-size:16pt; color:navy"> Send Me <SPAN STYLE="font-style; italic; color:green">Information!</SPAN> </BUTTON> 61; $ & $ $ .4 13 Button Demonstiation Microsoft Internet Exploiei ННЙ] H.Hr Действие кода продемонстри- ровано на рис. 1.4. Button Demonstration Send Information П E-Mail Address- (•.laeiNdri.e^twi Send Me Information! О О i Jsj W Ccrnfn* a Рис. 1.4. Web-страница демонстрации работы кнопки
26 Часть I. HTML и программирование сценариев Кнопки могут быть созданы с использованием всех возможностей, доступ- ных в HTML и таблицах стилей. Единственным недостатком элемента Button является то, что примитивные браузеры обрабатывают код HTML не как кнопку, а как обычный текст HTML. Поэтому для примитивных браузе- ров следует определить другую кнопку в элементе Button с помощью тега cinput>: CBUTTON STYLE="background:URL(cool.gif) yellow;font-weight:bold" > CP ALIGN=”Center">Calculatec/P> CP ALIGN=''Center” STYLE="font-style:italic">Nowc/P> c!— The following button is for older browsers. —> CINPUT TYPE=BUTTON VALUE= "Calculate Now"> c/BUTTON> , В браузерах, которые поддерживают элемент Button, тег <input> игнорирует- ся, а в браузерах низкого уровня, которые не поддерживают элемент Button, код HTML обрабатывается и отображается кнопка. ( Примечание } Данный метод, при использовании которого современные браузеры игнорируют альтернативный код HTML, в действительности создает недействительный до- кумент, поскольку определение типа документа HTML запрещает наличие эле- ментов input в элементе Button. Однако данный метод продемонстрирован здесь по причине того, что это единственный способ эффективного использо- вания элемента Button в примитивных браузерах, которые не поддерживают тег CBUTTONX Элемент Fieldset Элемент Fieldset используется для группирования элементов форм, анало- гично использованию тегов cdiv> для группирования связанного содержа- ния HTML. Элемент Fieldset был разработан преимущественно для обеспе- чения доступа, что позволяет страницам четко группировать наборы элемен- тов. Например, форма счета может содержать три элемента Fieldset: адрес отправки, раздел заказа, и информация биллинга. Если вы явно группируете поля с помощью элемента Fieldset, то браузер сможет легко отличить три группы. Элемент Fieldset обрабатывается Internet Explorer 4.0 для группи- рования окон в диалоговых окнах: <!— Группирование связанных элементов управления — > CFIELDSET> CLEGEND>SizeC/LEGEND> CINPUT TYPE=RADIO VALUE="Big" NAME="SIZE" ID="BIG"> CLABEL FOR="BIG">Bigc/LABEL> CINPUT TYPE=RADIO VALUE="Small" NAME="SIZE" ID="SMALL"> CLABEL FOR="SMALL">Sniallc/LABEL> C/FIELDSET>
Гпава 1. Обзор HTML и CSS 27 fti Fieldset DecnonsUalion - Miciosoll Internet txploiet Fie £dit Qo Information? Send InfviTnaWr F E-Mail Addies: [ Рис. 1.5. Элемент Fieldset содержит группу связанных элементов управления j My bariwb.’f На рис. 1.5 показан пример элемента Fieldset. Элемент Fieldset может содержать одиночную надпись в рамке набора по- лей. После надписи может быть помещено любое содержание HTML. Набор полей работает хорошо с примитивными браузерами и рекомендован для группирования связанных полей, по для группирования связанного содер- жания HTML должны быть, тем не менее, использованы теги <div>. Кнопки Defaults Cancel Internet Explorer 4.0 содержит две новых возможности: кнопка Submit теперь может работать как кнопка по умолчанию для формы. Это значит, что кнопка активизируется, когда пользователь нажимает клавишу <Enter> в любом месте формы. Кнопка Reset функционирует как кнопка Cancel для формы. Это значит, что кнопка активизируется при нажатии пользователем клавиши <Esc> в форме. Кнопки Default и Cancel работают в рамках текущей активной формы. По- этому если документ содержит множество форм, то текущие кнопки Default и Reset зависят от формы, с которой работает пользователь. Кнопки Submit и Reset могут так же работать за пределами формы, как кнопки по умолча- нию и отмены, но без установленного поведения по умолчанию. Для опре- деления поведения кнопок за пределами формы необходимы сценарии. На рис. 1.6 показаны кнопка по умолчанию и кнопка отмены. Кнопки по умолчанию с установленным тегом type=submit имеют дополнительную рамку. Рис. 1.6. Кнопка по умолчанию и кнопка отмены
гв Часть /. HTML и программирование сценариев Улучшенный элемент бегущей строки Элемент Marquee (бегущая строка) не является новым для Internet Explo- rer 4.0 — данный элемент впервые появился в Internet Explorer 3.0. Однако он уникален для Internet Explorer и не определен в HTML 4.0. В Internet Explorer 4.0 возможности элемента Marquee были расширены для отображения текста HTML и теперь можно прокручивать содержание не только влево и вправо, но также вверх и вниз. Элемент Marquee имеет столько же возможностей, а в некоторых случаях предоставляет даже большее количество возможностей, что и элемент Button, описанный выше. Элементы Marquee могут содержать эле- менты и даже таблицы, и все обработчики событий для элементов внутри элемента Marquee работают соответствующим образом. Кроме того, элемент Marquee представляет теперь полноценный объект в объектной модели. В главе 9 приведены примеры использования объекта элемента Marquee. Приведенный ниже код демонстрирует строку, бегущую в направлении снизу вверх: <!— HTML marquee — > <MARQUEE STYLE="height: 150px" DIRECTION="Up"> <TABLE> <CAPTION>Stock Ticker</CAPTION> <TRXTD>AAAA</TDXTD>100</TDX/TR> <TRXTD>ZZFD</TDXTD>45< /TDX /TR> </TABLE> </MARQUEE> Связывание данных В Internet Explorer 4.0 введены возможности связывания страницы HTML с источником данных на сервере и связывания различных HTML-элементов с полями и данными из источника данных. При загрузке страницы данные также отправляются с сервера и асинхронно появляются на странице. На высшем уровне это позволяет создавать Web-странипы типа клиент/сервер, на которых клиент манипулирует всеми данными. Например, поисковая машина может вернуть список узлов, которые клиент может отфильтровать и рассортировать, не связываясь с сервером. Данные мгновенно отобража- ются на странице без перезагрузки. Связывание данных HTML подробно обсуждается в главе 15. Каскадные таблицы стилей Каскадные таблицы стилей (Cascading Style Sheets, CSS) — это язык, который содержит набор свойств для определения внешнего вида документа. Специ- фикация CSS (CSS1) определяет свойства и описательный язык для уста-
Глава 1. Обзор HTML и CSS 29 новления связи свойств с элементами в документе. Internet Explorer 3.0 обеспечивал начальную поддержку CSS. В Internet Explorer 4.0 поддержка была расширена и улучшена. Понимание таблиц стилей необходимо для до- бавления динамического стиля страницы. (Динамический стиль (dynamic style) представляет собой модификацию таблицы стилей, связанную с доку- ментом посредством сценария). На узле консорциума W3C (www.w3.org) можно найти последнюю информацию о ново- введениях и элементах, поддерживаемых таблицами стилей. Таблицы стилей представляют собой абстракцию, в которой стиль докумен- та определяется отдельно от содержания или структуры. Существует три ме- тода добавления таблиц стилей в документ, доступных для Web-мастера — в целом, с повышением уровня сложности расширяются предоставляемые возможности с одновременным увеличением степени абстракции. Первый метод заключается в использовании таблицы внутренних стилей (inline style sheet). Внутренние стили (inline styles) определяются непосредственно в эле- менте. Второй метод заключается в использовании таблицы глобальных сти- лей (global style sheet) для определения стиля в начале документа. Третий, наиболее абстрактный и мощный метод заключается в использовании таб- лицы связанных стилей (linked style sheet) для определения стиля отдельно в другом документе. Внутренние стили мало отличаются от традиционного HTML. При исполь- зовании внутренних стилей внешний вид документа трудно изменить. Пре- имущество данного метода заключается в сокращенном объеме разметки и в том, что HTML может быть более полноценно использован для представле- ния содержимого презентации. Использование таблицы глобальных стилей позволяет более эффективно отделить презентацию от содержимого, а также дает возможность быстрого и независимого изменения стиля и обработки документа. Использование таблицы связанных стилей дает больше преиму- ществ, представляя содержимое в виде набора страниц или определяя целый Web-узел с помощью одного файла. Термин cascading (каскадные) в названии CSS указывает на возможность слияния различных таблиц стилей для создания единого определения стиля для элемента пли для целого документа. Это позволяет проводить предска- зуемое слияние таблицы стилей Web-узла с таблицей стилей документа и даже с внутренним стилем. Внутренние стили Внутренний стиль (inline style) является по существу таблицей стилей для одиночного экземпляра элемента и определен в*строке начального тега эле- мента. Таблица внутренних стилей определяется с использованием атрибута style, а данные для атрибута определяются с помощью языка таблицы сти-
30 Часть I. HTML и программирование сценариев лей. Ниже приведен кол HTML, который увеличивает содержание парагра- фа и выравнивает параграф по центру на желтом фоне: <Р STYLE™ "font-size:120%; text-align:center; background:yellow"> Создает желтый выровненный по центру параграф с большим размером шрифта. </Р> Внутренние стили помогут вам при изучении языка внутренних стилей или быстро изменить одиночный экземпляр элемента. Однако внутренние стили не соответствуют идеологии структурированного документа и плохо работа- ют при необходимости изменения внешнего вида ряда элементов в докумен- те, когда презентация и содержимое разделены не полностью. Для отделе- ния стиля документа от его структуры таблица стилей должна быть опреде- лена в заголовке документа или как отдельный файл, который связан с документом. Таблицы глобальных стилей Тег <style> используется для добавления таблицы глобальных стилей в до- кумент и обычно размещается в заголовке документа. Помещение всех сти- лей документа в одном месте упрощает изменение режима воспроизведения документа. Приведенный ниже пример таблицы стилей определяет воспро- изведение всех параграфов в документе. Для изменения режима воспроизве- дения параграфов требуется изменить только элемент style. Если бы ис- пользовались внутренние стили, то пришлось бы менять каждый параграф в документе отдельно. <html> <HEAD> <STYLE TYPE= "text/css"> P (font-size:120%; text-align:center; background:yellowJ </STYLE> </HEAD> <BODY> <P> Все параграфы теперь больше и выровнены по центру на желтом фоне. </Р> </BODY> </HTML> Атрибут type тега <style> определяет для языка таблицы стилей тип MIME. Internet Explorer 4.0 поддерживает только CSS и поэтому анализирует только таблицы стилей типа text/css. Если указан другой тип, который не поддер- живается браузером, то содержание блока стиля игнорируется. В случае пропуска атрибута type устанавливается язык- по умолчанию text/css. Хотя установка атрибута type необязательна, но она рекомендуется для четкого определения исходного кода.
Гпава 1. Обзор HTML и CSS 31 Для связи стиля с определенным элементом используется селектор (selector). В приведенном выше примере был создан простой селектор, который свя- зан со стилем во всех параграфах. Могут быть также определены более функциональные контекстуальные селекторы. Данные селекторы описываются в разделе "Определение таблицы стиля" ниже в данной главе. Таблицы связанных стилей Таблица связанных стилей (linked style sheet) находится во внешнем файле. Преимущество использования таблицы связанных стилей заключается в том, что все правила и стили могут быть определены и инкапсулированы в одном файле, который может быть совместно использован множеством страниц или даже целым Web-узлом: При использовании таблицы связанных стилей обработка всех параграфов целого Web-узла может быть изменена в одном документе. Таблица связанных стилей может также повысить производи- тельность, поскольку она кэшируется локально на диске клиента, отдельно от документа, так что каждый документ будет меньше по размеру, а инфор- мацию о стиле потребуется загрузить только один раз. Для определения таблицы связанных стилей в заголовке документа разме- щается тег <link>: <нтмь> <HEAD> CLINK REL= "stylesheet" TYPE= "text/css" HREF= "fancy.css"> </HEAD> <BODY> <P>This document uses the styles specified in fancy.css.</P> </BODY> </HTML> Атрибут rel определяет, что связанный файл является таблицей стилей, а атрибут type определяет тип MIME таблицы стилей. Атрибут href является указателем URL на внешнюю таблицу стилей. Таблица связанных стилей должна содержать только контекстуальные правила и определения стиля и не может включать код HTML. Определение таблицы стилей Для создания таблицы стилей внутри документа используется тот же син- таксис, который использовался при создании таблицы связанных стилей. В данном разделе описываются компоненты языка CSS. Язык CSS состоит из селекторов и правил представления (presentation rules). Селекторы (selec-
32 Часть I. HTML и программирование сценариев tors) определяют элементы, которые связаны с определенным правилом, а правила представления устанавливают методы обработки данных элементов. CSS содержит два типа селекторов: простые и контекстуальные. Простой селектор связывает элемент на основе его атрибутов или типа вне зависимо- сти от контекстуального положения внутри других элементов. Контексту- альные элементы являются более мощными — они могут связать правило с контейнерами определенного элемента, например, все теги <ем> внутри те- гов <р>. В базовой форме простой селектор может быть создан для связи определен- ного элемента, класса элементов или идентификатора (id) с определенным стилем. Приведенный ниже код демонстрирует ряд простых селекторов и их правил представления: <STYLE TYPE™ "Eext/css"> /‘Change all His to red.*/ Hl {color:red) /‘Устанавливает полужирное начертание всех элементов с тегом CLASS™ "special". (Make all elements with CLASS™ "special" boldface.) */ .special (font-weight:bold) /‘Размещает элемент с идентификатором ID™ на желтом фоне. (Give the ele- ment with ID= "special" a yellow background.) */ #special (background:yellow) /‘Устанавливает вывод элементов Hl с тегом CLASS™ "cool" с большим интер- валом. (Give the Hl elements with CLASS™ "cool" wider letter spacing.) */ Hl.cool (letter-spacing:2px) </STYLE> Селекторы могут быть перечислены через запятую, что позволяет одновре- менно описать несколько селекторов: /‘Устанавливает для всех заголовков одинаковые правила. */ Hl, Н2, НЗ, Н4, Н5, Н6 {color:red;background:yellow) Контекстуальные селекторы определяют иерархию контейнеров, с которой должен быть связан стиль. Иерархия контейнеров определяется порядком элементов в списке через запятую. Например, приведенный ниже оператор определяет правило для всех элементов ем, находящихся в элементе р: Р ЕМ {color:blue) Каждый селектор может ссылаться на теги class, id или тип элемента. Ни- же приведена более сложная версия контекстуального селектора: /* Любой элемент тега CLASS™ "cool", который находится внутри элемента L1 тега CLASS™ "special" и далее находится внутри элемента UL, будет исполь- зовать данный стиль. */ UL LI.special .cool{font-weight:bolder; font-size:120%)
Глава 1. Обзор HTML и CSS 33 Все элементы контекстуального селектора являются нечувствительными к регистру — например, .cool это то же самое, что и .ссоь. Псевдоклассы Псевдокласс (pseudo-class) состоит из элементов одного типа, которые удов- летворяют определенному контекстуальному критерию. Например, просмот- ренные элементы Anchor (якорь) представляют собой псевдокласс visited. Активные и не просмотренные ссылки представляют собой исевдоклассы active и link, соответственно. Псевдокласс в таблице стилей отделяется двоеточием (:): A: link {color:green) :link {color:green( Во втором примере опущено имя элемента (а), так как только ссылки имеют псевдокласс link. Псевдокласс может быть использован так же, как класс или указатель id и является нечувствительным к регистру. В спецификации CSS1 определены псевдоэлементы, сходные с псевдоклассамп, для первой строки и первой буквы в элементе, но Internet Explorer 4.0 в настоящее вре- мя поддерживает только исевдоклассы anchor. Последовательность каскадирования На одни и те же элементы могут ссылаться несколько селекторов. CSS оп- ределяет последовательность каскадирования (cascading order), которая ис- пользуется для разрешения проблем перекрывания областей действия селек- торов и правил. Последовательность каскадирования объединяет вее прави- ла. применимые к элементу, путем сортировки на основе их определений. Например, элемент strong, находящийся в элементе hi, может иметь правила представления, определенные селектором hi, селектором strong и контекстуальным селектором для элементов strong внутри элементов ш. Параметр каскадирования в CSS определяет порядок объединения данных трех правил. В общем, правило для более конкретного контекстуального се- лектора отбрасывает правило для менее конкретного селектора, а правила, определенные ниже в исходной таблице стилей или документе, имеют более высокий приоритет. Элементы CSS В данном разделе представлены примеры некоторых новых элементов CSS, которые поддерживаются в Internet Explorer Ф.О. Некоторые из них могут быть использованы для замены широко используемых приемов размещения содержания, в основе которых лежит использование таблиц для выравнива-
34 Часть I. HTML и программирование сценариев ния содержания. Данные элементы преимущественно содержатся в допол- нительных рабочих проектах и предложениях и отсутствуют в главной спе- цификации CSS1. Выравнивание текста Internet Explorer 4.0 обеспечивает полную поддержку выравнивания текста по левому и правому краям и по ширине. Выравнивание по ширине являет- ся новым в Internet Explorer 4.0 и позволяет выравнивать текст с обеих сто- рон. Выравнивание задается с помощью свойства text-align в CSS: <Р STYLE= "text-align:justify"> Данный параграф выравнен с помощью свойства text-align в CSS. </Р> Маркированные списки С помощью свойства list-style можно использовать символы маркера, оп- ределенные как файлы GIF, вместо встроенных символов. Символы маркера могут быть определены для списка в целом или индивидуальных элементов списка. Данный метод не работает с браузерами низкого уровня, которые отображает список с использованием стандартных символов маркера. При- веденный ниже код HTML демонстрирует замену стандартного символа маркера: <HTML> <HEAD> <TITLE>Custom Bulleted List</TITLE> <STYLE TYPE="text/css”> /‘Отображает файл cool.gif вместо маркера по умолчанию. */ UL { list-style-image: URL(cool.gif)( </STYLE> </HEAD> <BODY> <UL> <LI>You can provide a custom bullet! <LI>The bullets are replaced with cool.gif</LI> <LI STYLE="list-style-image: none; list-style-type: square">Each bullet can be different </UL> </BODY> </HTML> На рис. 1.7 показан список с использованием индивидуальных символов маркера.
Гпава 1. Обзор HTML и CSS 35 В List Bullets - Miciotoll Internet Ex... H(rIE3 | HTML 4 0 consists of • Table enhancements • Form enhancements • Script element • and more. Рис. 1.7. Маркированный список с индивидуальными символами маркера Создание врезок Врезки (sidebars) традиционно создавались с помощью таблиц, но теперь в CSS появилось свойство float. Тексту может быть назначен класс с помо- щью тегов <span> или <div>, а затем в правиле стиля для данного класса может быть установлено свойство float. Используя свойство property можно легко создать два типа врезок: □ Врезок, которые выровнены по левому или правому краю и окружены текстом, подобно рисунку. □ Врезки, которые появляются за пределами полей общего документа. Соз- дание данного типа врезок требует манипулирования полями элемента. Ниже приведен пример создания этих типов врезок: <HTML> <HEAD>' <Т1ТЬЕ>Пример врезки </TITLE> <STYLE TYPE="text/css"> BODY {margin-left: 1.50pt; margin-right: Opt) .outflow, .inflow {float: left; width:150pt; color: navy} .outflow {margin-left: -150pt; width: 150pt} </STYLE> </HEAD> <BODY> <Н1>Пример врезки </Н1> <DIV CLASS="inflow"> Обратите внимание, что текст огибает данную врезку. </DIV> <Р>В данном примере продемонстрирована врезка, которая находится в тексте документа. Текст огибает врезку. </Р> <DIV CLASS="outflow"> Данная врезка находится в левом пол® документа. </DIV> <Р>
36 Часть I. HTML и программирование сценариев В этом примере продемонстрированы методы манипуляции полями доку- мента для свободного размещения врезки на поле. Путем настройки полей вы можете поместить врезку поверх содержания документа. </Р> </BODY> </HTML> На рис. 1.8 проиллюстрированы оба типа врезок. П Sideb<M Ех.м«()1е Miciotoil Interne! Explotet ИИЙ Е'Я V'**’ Go fjvtztM HI ...-------------------------------------------------J Sidebar Example Notice that the text wraps This example demonstrates a " around this sidebar. sidebar that exists within the flow of the document The contents wrap around the sidebar and continue below it Tltis sidebar appears in the left This example demonstrates how to manipulate a document's • £ margin of the document margins to force a sidebar tv floa^ in the margin By adjusting the .-a margins, you can make the sidebar overlay the flow of the contents. ♦ J Рис. 1.8. Врезка с текстом вокруг нее и врезка на полях слева Сравнение свойств visibility и display С Visibility V» Duplay - Microsoft Internet Explorei fOi уНл (j-j Fsvurtec ВИВ visibility vs. display Ф Using the CSS visibility Property , ( This is the contents before. This is the contents before ] 'Ihis is the contents cnstde. Ц This is the contests after. Itos и the contents after ’ Using the CSS display Property lbs is the contents before ‘Ibis is the contents before x I This ts the contents inside This is the contents after $ ТЪи is the content; after Рис. 1.9. Эффект использования свойств visibility и display Спецификация CSSI определяет свойство display для удаления элементов из представления до- кумента. Рабочий проект но пози- ционированию CSS содержит до- полнительное СВОЙСТВО visibility, которое позволяет создавать про- зрачные элементы в тексте доку- мента. Эти свойства используются для получения различных эффек- тов при обработке документа. Ус- тановка значения hidden для свойства vi sibi 1ity определяет, что содержание страницы являет- ся прозрачным, то есть невиди- мым. Установка значения попе длц свойства display приводит к тому, что браузер игнорирует эле-, мент. На рис. 1.9 показано ис-
Гпава 1. Обзор HTML и CSS 37 пользование свойств visibility и display. Для правого столбца установле- ны свойства visibility: hidden или display:none. Содержание левого столбца отображается полностью. При использовании свойства display:попе невидимые элементы не занимают места на экране. Управление курсором Свойство cursor в CSS используется для индивидуальной настройки указа- теля мыши. Это свойство особенно полезно, когда с традиционными тек- стовыми элементами связан сценарий. Например, использование традици- онного I-образного курсора с текстом, когда предполагается, что пользова- тель должен нажать на кнопку, будет неуместным. В данном случае будет логичным использование стрелки или другого подобного курсора. В табл. 1.1 перечислены установки для свойства cursor, определенного на данный момент в CSS. Эти курсоры можно найти в примерах для главы 1 на прилагаемом компакт-диске. Таблица 1.1. Установка свойства cursor Значение Описание auto Браузер самостоятельно определяет, каким должен быть отображен курсор на основе текущего контекста crosshair Простой курсор-крест default Обычно стрелка. Независимый от платформы курсор по умолчанию hand Курсор в виде руки. Используется для представления области на экране, по которой можно щелкнуть мышью text Обычно l-образный курсор. Используется для индикации редакти- руемого текста help Обычно курсор имеет форму знака вопроса или шара. Указывает на доступность справки для объекта, который находится под курсором e-resize, ne-resizc, nw-resize, ri-resize, se-resize, sw-resize, s-resize, w—resize Различные курсоры в виде стрелок. Используются для представления операции изменения размера — например, когда пользователь щел- кает по рамке окна для изменения размера окна move Используется для указания, что элемент может быть перемещен wait Обычно представляет собой песочные часы. Указывает на паузу вследствие занятости программы
Зв Часть I. HTML и программирование сценариев Поддержка CSS для внутренних элементов В Internet Explorer 4.0 текст, кнопка и элементы бегущей строки полностью полдерживают таблицы стилей. Элемент Select имеет ограниченную под- держку таблиц стилей. Для предотвращения проблем с браузерами предше- ствующих поколений внутренние элементы не наследуют таблицы стилей от родительских элементов. Напротив, правила стилей должны быть связаны с определенными элементами по типу элемента или атрибутам class или id. Приведенная ниже простая таблица стилей форматирует все элементы input в классе text как текст зеленого цвета с полужирным начертанием: <STYLE TYPE= "text/css"> INPUT.text (color:green; font-weight:bold} </STYLE> CINPUT CLASS= "text" TYPE=TEXT VALUE= "Green Bold Text"> Использование атрибута class гарантирует, что будут изменены только эле- менты класса text. Данный метод требует некоторой избыточности в атри- бутах type и class, поскольку селектор в CSS, который связывает элементы со стилями, не распознает произвольные атрибуты. В CSS определено свя- зывание стилей с элементами только на основе атрибутов class или id, или типа элемента. Внедрение индивидуальных шрифтов До появления Internet Explorer 4.0 Web-мастера должны были использовать встроенные шрифты браузера или использовать шрифты, доступные в сис- теме. Internet Explorer 4.0 предоставляет Web-мастеру возможность указания отображаемых шрифтов, которые загружаются вместе с Web-страницей, что гарантирует правильную обработку страницы. Загружаемый шрифт опреде- ляется с помощью новых элементов в синтаксисе CSS. Ниже приведен син- таксис для определения загружаемого шрифта в таблице стилей: 0font-face (font-family:fontName; sre:url(filename.eot) Значение fontName, на которое впоследствии ссылается свойство CSS font-family, определяется пользователем. Ниже приведен полный пример: <STYLE TYPE= "text/css"> 0font-face ( font-family:demoFont; src:url(http://somewhere.com/coolFont.eot)} Hl (font-family:demoFont, Arial, sans-serif} </STYLE> <H1> Текст отображается с использованием загружаемого шрифта demoFont. </Н1>
Глава 1. Обзор HTML и CSS 39 После определения нового шрифта его имя может быть использовано как действительное для свойства font-family. Свойство font-family может быть связано с равным списком шрифтов, так что если первый в списке шрифт не может быть загружен, то браузер попытается загрузить следующий шрифт или семейство шрифтов. В данном примере последним определенным шрифтом является шрифт sans-serif, что позволяет браузеру использовать любой шрифт семейства sans-serif для воспроизведения элемента. Пользовательские установки Internet Explorer 4.0 поддерживает возможность создания Web-страниц, ко- торые автоматически адаптируются к пользовательской системе. Для опре- деления пользовательских установок цвета и шрифта имеется набор новых ключевых слов. Демонстрационная страница, которая отображает формати- рованный текст на основе системных установок, включена в примеры для главы 1 на прилагаемом компакт-диске. В табл. 1.2 содержимся набор новых ключевых слов, определяющих цвет, доступных в Internet Explorer 4.0. (В списке не указаны имеющиеся цвета, которые могут быть определены для любого атрибута цвета CSS). Полный список именованных цветов, а также демонстрационная страница с отобра- жением данных цветов, находятся на прилагаемом компакт-диске. В табл. 1.3 перечислены ключевые слова шрифтов, которые представляю! текущие пользовательские установки системы. Данные значения могут быть использованы только для свойства font и не могут быть использованы со свойством font-family, поскольку свойство font-family автоматически оп- ределяется на основе пользовательских установок системы. Таблица 1.2. Новые ключевые слова цвета в Internet Explorer 4.0 Ключевое слово Описание activeborder Цвет рамки активного окна activecaption Цвет заголовка активного окна appworkspace Цвет фона приложений многодокументного интер- фейса (multiple document interface, MDI) background Цвет фона рабочего стола buttonface Цвет кнопок buttonhighlight Цвет выделения для кнопок buttonshadow Цвет тени для кнопок buttontext Цвет текста на кнопках
40 Часть I. HTML и программирование сценариев Таблица 1.2 (окончание) Ключевое слово Описание captiontext Цвет текста в заголовке, в окне и кнопках стрелок на полосе прокрутки graytext Цвет серого (отключенного текста), Установлен рав- ным 0, если текущий драйвер дисплея не поддержи- вает серый цвет highlight Цвет выбранных пунктов в элементе highlighttext Цвет текста пунктов, выбранных в элементе inactiveborder Цвет рамки неактивного окна inactivecaption Цвет заголовка неактивного окна inactivecaptiontext Цвет текста в неактивном заголовке i nfobackground Цвет текста для всплывающей подсказки infotext Цвет текста для всплывающей подсказки menu Цвет фона меню menutext Цвет текста в меню scrollbar Цвет фона полосы прокрутки threeddarkshadow Темный цвет тени для объемных элементов threedface Цвет объемных элементов threedhighlight Яркий цвет объемных элементов threedlightshadow Яркий цвет тени объемных элементов threedshadow Цвет тени для объемных элементов window Цвет фона окна windowframe Цвет фрейма окна windowtext Цвет текста в окнах Таблица 1.3. Новые ключевые слова системных шрифтов в Internet Explorer 4.0 Ключевое слово Описание caption Шрифт, используемый для элементов с заголовками (кнопок, раскрывающихся списков и так далее) icon Шрифт, используемый для надписей значков menu Шрифт, используемый в меню
Глава 1. Обзор HTML и CSS 41 Таблица 1.3 (окончание) Ключевое слово Описание messagebox Шрифт, используемый в диалоговых окнах smallcaption Шрифт, используемый в надписях для малых элементов statusbar Шрифт, используемый в строках состояния окон Позиционирование CSS Internet Explorer 4.0 также поддерживает новый проект CSS, CSS-Р, который предоставляет большие возможности при позиционировании элементов. Совместное использование новых расширений со сценариями позволяет создавать анимированные и движущиеся элементы. Данный элемент пре- доставляет Web-мастеру осуществлять полный контроль нал разметкой стра- ницы и дает возможность управления положением и отношениями между элементами. В главе 12 приводится описание синтаксиса для позиционирования элементов <• помощью CSS, а также поддержки позиционирования элементов с помощью сценариев. Эффекты фильтров и перехода Internet Explorer 4.0 также поддерживает набор фильтров и переходов, кото- рые могут быть связаны с HTML-содержанием. Фильтры могут быть непо- средственно применены к тексту в документе. Переходы позволяют добав- лять в документ или элементы документа такие эффекты, как растворение и скольжение элементов. Например, вы можете сделать текст рельефным или полупрозрачным и сделать так, что страницы будут постепенно исчезать и снова появляться при их открытии. Эти функциональные возможности под- держиваются посредством нового свойства CSS Cilter. Проверка определения типа документа HTML Поскольку HTML представляет собой приложение SGML, то возможно соз- дание структурированных документов. К сожалению, недавние исследова- ния Web показали, что большинство Web-страниц нс являются в действи- тельности документами HTML. Отчасти в этом виноваты браузеры, по- скольку они очень снисходительны при анализе документов и часто пытаются расшифровать творение Wcb-мастера, вместо того, чтобы отбра- сывать недействительные документы.
42 Часть I. HTML и программирование сценариев С введением динамического HTML и CSS структуре придается большее значение. Правильно структурированные страницы работают надежно в раз- личных браузерах. Сценарии выполняются более предсказуемо, поскольку отсутствует неоднозначность в описании документа. Архитектура событий, предлагаемая динамическим HTML, также полагается в основном на струк- туру документа. Для понимания процедуры создания правильного документа HTML необхо- димо уметь читать определение типа документа (document type definition, DTD). DTD определяет набор действительных элементов, идентифицирует элементы, которые могут находиться в других элементах, и определяет дей- ствительные атрибуты для каждого элемента. В данном разделе изложены основные положения DTD, которые необходимы для чтения и анализа оп- ределений типов документов. В разделе отсутствуют подробные описания процедуры создания индивидуальных DTD — это тема для отдельной книги. Определение элемента Элемент в DTD определяется с помощью ключевого слова element. Опреде- ление элемента устанавливает, содержит ли элемент другие элементы и не- обходимость наличия тегов начала и конца. Ниже приведен код HTML, который демонстрирует прототип для определения элемента: <!ELEMENT elementName beginTag endTag contentModel> Заменители тегов beginTag и endTag могут быть дефисом ( ) или симво- лом о. Дефис указывает, что тег требуется, а символ о определяет, что тег необязателен. Заменитель content Model может быть равен empty, это значит, что элемент не может содержать другие элементы пли может быть специфи- кацией действительного содержания элемента. Приведенный ниже код оп- ределяет элемент Body, в котором теги начала и конца являются необязательными: <!element body о о tbody.content —Теги начала и конца являются необязательными, содержат body.content. — > Несмотря на то, что в HTML имеется много элементов, которые поддержи- вают необязательные теги начала и конца, рекомендуется всегда явно указы- вать данные теги. Это делает документ более легко читаемым и доступным для повторного использования, особенно для тех, кто не разбирается в сложностях HTML. В отсутствие этих разделителей браузер будет предполо- жительно устанавливать их местоположение на основе контекста. В приведенном выше определении элемента вебу установлено, что элемент может содержать фрагмент %body.content. Символ ? в данном определителе указывает, что содержание документа определяется посредством макроса
Гпава 1. Обзор HTML и CSS 43 (который называется компонентом в SGML). Определение <’ entity %body. content... > указывает элементы, которые могут содержаться в эле- менте Body. Такие макросы полезны, поскольку они допускают повторное использование моделей содержания многочисленными элементами, делая DTD более компактным и простым в использовании. Модели содержания также могут быть определены непосредственно в строке. Например, приве- денный ниже код определяет элемент мар, который может содержать только элементы Area. <!ELEMENT MAP -- (AREA)*> Набор действительных элементов в модели содержания определяется с по- мощью языка простых регулярных выражений. Квалификатор * после тега (area) указывает, что в элементе Мар может содержаться любое число эле- ментов Area. Определение атрибутов Атрибуты определяются аналогично элементам. Списки атрибутов опреде- ляются с помощью ключевого слова iattlist. Атрибуты для элемента Body определяются следующим образом: <IATTLIST BODY iattrs; --- id, class, style, lang, dir, events - - % focus; background %URL #IMPLIED - фон документа в виде ткани - topmargin; CDATA «IMPLIED leftmargin; CDATA «IMPLIED %body-color-attrs; — bgcolor, text, link, vlink, alink — onLoad %script «IMPLIED — внутреннее событие- onUnload %script «IMPLIED — внутреннее событие - Первый тег ниже ключевого слова jattlist определяет элемент, после ко- торого указан список связанных с ним атрибутов. Каждый атрибут пред- ставляет собой макрос, указывающий на другой список атрибутов или опре- деление типа данных, которое указывает, является ли атрибут необходимым или подразумеваемым. Макрос может быть использован для связи группы атрибутов с элементом или даже для определения типа данных. Определение компонента Компонент (entity) представляет собой макрос,-который может быть повтор- но использован в DTD. Ниже показан компонент attrs, используемый эле- ментом Body, вместе с компонентом style. Обратите внимание, что компо-
44 Часть I. HTML и программирование сценариев нент attrs указывает на дополнительные компоненты: style, ii8n (интер- национализация) И events. <!ENTITY % attrs "Sstyle %il8n -tevents"> <!ENTITY % style "id ID UIMPLIED — document-wide unique id — class CDATA #IMPLIED — comma list of class values — style CDATA DIMPLIED — associated style info — title CDATA DIMPLIED — advisory text — Компонент body.content также определяется с помощью других компонентов: <!ENTITY % body.content "Sheading I %text tblock | ADDRESS)*”) Данное определение указывает, что тело может содержать любое количество элементов, определенных с помощью компонентов Sheading, next, и ^Ысск и любое ЧИСЛО элементов Address. Одним из наиболее сложных элементов в HTML является элемент Table. Ниже приведено определение элемента Table: <!ELEMENT table ---- (caption?, (col*Icolgroup*), thead?, tfoot?, tbody+)> <!ELEMENT caption - (%text;)+> <!ELEMENT thead - 0 (tr+)> <!ELEMENT tfoot - 0 (tr+)> <!ELEMENT tbody 0 0 (tr+)> < !ELEMENT colgroup - 0 (col*)> < !ELEMENT col - 0 EMPTY» < !ELEMENT tr - 0 (th)td)+> < !ELEMENT (thltd) -0 %body.content» Содержание таблицы может начинаться с одиночного необязательного заго- ловка, после которого указано любое число элементов со) или CoiGroup, за- тем одиночный необязательный элемент Thead и необязательный элемент Tfoot, после которого расположен один или большее число элементов Tbody. Разделитель в виде запятой определяет последовательность элементов. По- этому если указывается элемент caption, то он должен быть первым элемен- том в таблице. Может показаться странным, что в таблице запрещено помещение элемента tr непосредственно ниже таблицы. Это не означает, что почти все таблицы на Web являются недействительными. Элемент TBody определен с необяза- тельными тегами начала и копна. Поэтому тег тк за пределами тнеаД и tfoot неявно находится в теге твоДу. Данное отношение в дальнейшем поддержи- вается в объектной модели, где элемент твоДу всегда синтезируется. Синте- зированный элемент в объектной модели представляйi элемент, который
Глава 1. Обзор HTML и CSS 45 неявно принадлежит всем документам, независимо от того, определен он явно или нет. Например, считается, что все документы имеют элементы HTML, Head, Body В объектной Модели. Синтезирманные элементы в объектной модели подробно обсуждаются в главе 7. На этом заканчивается краткое введение в мир определений типов докумен- тов (DTD) языка SGML. Теперь вы умеете читать определения типов доку- ментов HTML и создавать действительные документы HTML. За более под- робной информацией об HTML и для получения действительных DTD для всех версий HTML, обратитесь на Web-узел консорциума W3C (www.w3.org). С определениями типов документов, используемых в Internet Explorer 4.0, можно ознакомиться на Web-узле компании Microsoft (www.microsoft.com).
hi ЕЕ Глава 2 Основы сценариев HTML Объектная .модель динамического HTML (Dynamic HTML object model) была разработана на основе объектных моделей, включенных в Microsoft Internet Explorer 3.0 и Netscape Navigator 3.0. В данной главе приведен исторический обзор со сравнением старых объектных моделей и модели динамического HMTL и показан уровень поддержки данной модели различными версиями браузеров. Языки написания сценариев развивались наряду е объектными моделями HTML. Путем внедрения сценариев в документы вы можете обращаться к объектам HTML для манипулирования элементами Web-страниц. Здесь приведено описание этого мощного метода программирования. В главе рассмотрены следующие темы: □ Объектная иерархия динамического HTML. Объектная иерархия пред- ставляет собой интерфейс прикладного программирования (application programming interface, API) для создания живых интерактивных страниц. Объекты в иерархии представляют браузер и элементы страницы HTML. В данном разделе обсуждаются объектные модели, поддерживаемые Internet Explorer 3.0 и Netscape Navigator 3.0 и 4.0 и дается сравнение этих моделей с объектной моделью динамического HTML, поддерживаемой I niernet Explorer 4.0. □ Написание сценариев. Доступ к объектной модели динамического HTML осуществляется посредством написания сценариев и связывания их с до- кументом HTML. Сценарий присоединяется к документу HTML с помо- щью элемента Script, который содержит выполняемую прщрамму на оп- ределенном языке. Элемент script может быть также использован для связывания с документом внешних библиотек сценариев. □ Выбор языка написания сценариев: JavaScript или VBScript. На Web ис- пользуются два главных языка программирования: JavaScript и VBScript
Глава 2. Основы сценариев HTML 47 Оба языка могут манипулировать объектами динамического HTML. В этом разделе дано описание выбора языка в определенных ситуациях. □ Передовые методы JavaScript. Здесь обсуждаются некоторые методы JavaScript, которые используются в книге. Раздел не является руковод- ством по программированию на языке JavaScript и содержит материал, предназначенный для знакомства с некоторыми интересными элемента- ми языка JavaScript и их связью с динамическим HTML. □ Использование сценариев и безопасность в Web. Безопасность является общей заботой всех участников Web. Языки программирования наклады- вают определенные ограничения для обеспечения безопасности клиента, которые должны быть известны программисту. В данном разделе вводит- ся модель безопасности для динамического HTML. Дополнительные во- просы безопасности обсуждаются на протяжении всей книги. ( Примечание ) В данной главе используются элементы объектной модели динамического HTML в целях демонстрации различных методов. Для каждого элемента дана ссылка на главу, в которой дается подробное описание элемента. Иерархия объектов динамического HTML Минимальная модель объектов HTML была впервые введена как часть реа- лизации JavaScript в Netscape Navigator 2.0. Исходная модель предоставляла возможность манипулирования только малым количеством параметров до- кумента с помощью языка написания сценариев. Однако эта модель зало- жила основу для последующих версий объектных моделей. Internet Explorer 3.0 отделял исходную объектную модель для описания до- кумента от реализации языка. Это положило основу для требования незави- симости от языка динамического HTML. Internet Explorer 4.0 построен на данной модели для полного представления всех параметров документа. На рис. 2.1 показана объектная модель, поддерживаемая internet Explorei 4.0. Эволюция иерархии динамического HTML В приведенных ниже списках представлена эволюция поддержки объектов в различных браузерах. Internet Explorer 3.0 поддерживает следующие объекты: □ anchors □ elements □ document □ forms □ document.frames П history
48 Часть I. HTML и программирование сценариев □ links □ location □ navigator □ window □ wi ndow.f tames window Netscape Navigator 3.0 поддерживал тот же набор объектов, что и Internet Explorer 3.0 за исключением объекта document.frames и двух дополнитель- ных объектов: □ applets □ images Internet Explorer 4.0 поддерживает те же объекты, что и Internet Explorer 3.0 и Netscape Navigator 3.0, а также добавляет поддержку для следующих элементов: □ all CJ body □ client Information □ event □ screen □ scripts □ selection □ stylesheets Данные списки полезны при сравне- нии уровня необходимых функцио- нальных возможностей с выбранным набором браузеров. Для совместимо- сти с Internet Explorer 3.0 сценарии должны быть ограничены возможно- стями internet Explorer 3.0, или про- грамма должна проверять версию н название браузера для обеспечения плавного снижения возможностей (деградации). Рис. 2.1. Объектная модель Internet Explorer 4.0
Гпава 2. Основы сценариев HTML 49 Объект window (окно) представляет собой объект высшего уровня в объект- ной модели HTML п является фреймом для объекта document (документ). Все взаимосвязи с документом поддерживаются посредством окна. Объект window также представляет информацию об URL текущего документа, об URL, которые были просмотрены клиентом ранее, и информацию о типе текущего документа. Окно может содержать различные типы документов в зависимости от типа MIME. Существует два типа документов HTML: традиционный документ HTML и набор фреймов (frameset) HTML. Для обоих типов содержание до- кумента выводится посредством объекта document. Поскольку наборы фрей- мов разделяют экран на многочисленные фреймы, каждый индивидуальный фрейм также выводится посредством семейства окна frames. Каждый фрейм в этом семействе в действительности представляет другой объект window и потенциально другой документ пли другое семейство frames и так далее. Наборы фреймов подробно обсуждаются в главе 5. Эволюционное (революционное) развитие динамического HTML Netscape Navigator 2.0 и Internet Explorer 3.0 ввели базовые объектные моде- ли для HTML-документов. Однако уровень поддержки был преимуществен- но ограничен условной логикой в ходе загрузки страниц и проверки форм. Не были разрешены изменения, которые могли бы изменить форму или воспроизведение документа. Internet Explorer 4.0 преодолел данное ограни- чение путем использования объектной модели, которая выводит весь доку- мент целиком. Вместо определения совершенно новой объектной модели разработчики создали объектную модель динамического HTML, которая содержит в своем составе текущую модель. Кроме того, объектная модель динамического HTML согласуется с текущими парадигмами программирования, что позво- ляет разработчикам использовать накопленные знания. Если вы знакомы с написанием сценариев для Internet Explorer 3.0 пли Netscape Navigator 3.0, то у вас уже есть базовые сведения для изучения динамического HTML. Поддержка старых версий браузеров Плавная деградация, которая является неотъемлемой частью HTML, невоз- можна в языках написания сценариев. Если анализатор нс может иденти- фицировать тег HMTL, то тег игнорируется. В результате представление со- держания соответствующего элемента может отличаться от предполагаемого. В сценариях игнорировать инструкции недопустимо — пропуск строки в сценарии может оказаться фатальным для остальной части программы, так
so Часть I. HTML и программирование сценариев как каждая строка программы может создавать или изменять состояние до- кумента. Поэтому при создании сценариев для разных браузеров и версий не следует игнорировать деградацию. Необходимо тщательно спланировать ее при конструировании и разработке страницы. Динамический HTML предоставляет возможности, которые были недоступ- ны в предыдущих версиях HTML. Вы можете создавать страницы с исполь- зованием множества элементов динамического HTML, которые будут рабо- тать во всех браузерах. На протяжении данной книги обсуждаются методы, которые помогут пользователю при написании программ, допускающих плавную деградацию. В некоторых случаях программа выдает визуальный сигнал и деградация обычно примитивна. В других случаях, в зависимости от цели сценария единственным решением является создание отдельных страниц, которые предоставляют тс же возможности отличным образом. В целом, чем более динамична страница, тем тщательнее следует продумывать режимы воспро- изведения страницы в примитивных браузерах (браузерах с мепыпимп воз- можностями). На рис. 2.2 показана страница, разработанная с использова- нием динамического HTML, которая запущена в двух браузерах: Internet Explorer 3.0 (слева) и Internet Explorer 4.0 (справа). Версия Internet Explorer 3.0 отображает расширенную примитивную таблицу, тогда как Internet Explorer 4.0 выводит красиво оформленное оглавление. Q Table ol Contents * Microsoft Internet Expl... МГЯИ X®W Со Fjvomet Цо1р I ИЯ -—3 i! -^Overview of JIIML and CSS HTML4 0 CSS Features «X : CSS Positioning vj System Settings A' ; ^Fundamentals of HTML Scripting 5»* | CJDynamic HTML Event Model C-JThe Browser Window i ‘^Window and Frame Management I Scrolling Window Modal Dialogs •'») Window Manager ;*•’ Frameset Hierarchy Frameset Browser ! %’ ________ Й Рис. 2.2. Страница динамического HTML в Internet Explorer 3.0 (слева) и Internet Explorer 4.0 (справа)
Глава 2. Основы сценариев HTML 51 Следует также помнить, что в существующих реализациях могут быть ошиб- ки и несовместимости. Поэтому даже если страница, разработанная для за- пуска в различных браузерах различных версий, использует обычный набор объектов и членов (свойств и методов), опа должна быть протестирована на всех необходимых платформах. Динамическое переформатирование Возможность доступа к любому параметру страницы и его изменения де- монстрирует одно из ключевых нововведений, доступное в динамическом HTML. Старые браузеры, хотя и позволяли осуществлять некоторые изме- нения в документе, были не способны выполнять переформатирование (reflow) документа без сложных сценариев, которые создавали совершенно новые документы. Динамический HTML свободен от этих ограничений. Когда сценарий манипулирует и изменяет атрибуты элемента или таблицы стилей, или модифицирует содержание, то документ соответствующим обра- зом изменяет представление страницы на основе повой информации. Динамический HTML был разработан для использования преимуществ су- ществующих рекомендаций и рабочих проектов HTML и CSS (Cascading Style Sheets). Разработчикам нс надо изучать новую модель представления страницы — объектная модель динамического HTML представляет отраже- ние документа в языке написания сценариев. Например, сценарий может изменить атрибут class любого элемента HTML. В языке написания сцена- риев атрибут class, подобно другим атрибутам, представляется как свойство элемента — в данном случае свойство className. Изменение атрибута внут- ренне совместимо с открытием файла пользователем в текстовом редакторе и изменением атрибута в исходном файле. Данная модель гарантирует, что по мерс развития HTML и CSS будет соответствующим образом изменяться и объектная модель. Создание сценариев Сценарии не являются единственным способом доступа к объектной модели динамического HTML. Доступ к объектной модели динамического HTML может осуществляться тремя способами: □ Посредством сценариев внутри HTML-страницы или сценариев, па кото- рые ссылается HTML-страница. Эти сценарии могут обращаться к со- держанию текущего документа или документов из того же домена в дру- гих фреймах или окнах. □ Посредством внедренных апплетов пли элементов управления, которые находятся па странице. □ Посредством хостов, которые находятся за'пределами или рядом с брау- зером. Например, диалоговое окно Find в Internet Explorer 4.0 было соз- дано с помощью динамического HTML.
52 Часть I. HTML и программирование сценариев Все три метода манипулируют динамическим HTML сходными способами. В данной книге внимание сфокусировано па первом методе, на обращении к объектной модели посредством сценариев, которые связаны с документом HTML. Однако вес концепции и методы, представленные в книге, также могут быть применены к остальным двум методам. Элемент Script Сценарии на странице могут быть связаны с документом с использованием одного из трех методов. Наиболее общий метод заключается в помещении программы в элемент script. (Два остальных метода помещают программу в отдельный файл и ссылаются на него при помощи тега <script> или поме- щают программу в атрибут события в другом теге). Элемент script пред- ставляет собой контейнер для программы, написанной на определенном языке программирования. Элемент script может содержать программу, на- ходящуюся в документе, или ссылаться на внешний файл. Сценарии, со- держащиеся внутри элемента Script, могут быть связаны с элементом при помощи программы, специальных атрибутов элемента Script или посредст- вом зависимого от языка механизма. Индивидуальные элементы могут иметь сценарии, которые связаны с ними непосредственно атрибутами событий, представленных в самом элементе. Ниже приведен синтаксис элемента Script: <SCRIPT LANGUAGE» "language.Name" (TYPE = "MIMEtype"] [SRC= "optionalFile”J [DEFER]» Script statements </SCRIPT> Язык написания сценариев определяется с помощью атрибута ianguage. Приведенная ниже программа демонстрирует определение сценария для языков JavaScript и VBScript: <SCRIPT LANGUAGE» "VBScript» 'VBScript code c/SCRIPT» <SCRIPT LANGUAGE» "JavaScript"» //Программа JavaScript </SCRIPT» Примечание J В VBScript комментарии предваряются символом апострофа (') В языке JavaScript перед. комментариями ставятся символы // (это значит что вся остальная часть строки является комментарием), или комментарий заключается между символами /* и * / . Поисковые машины игнорируют текст комментариев
Гпава 2. Основы сценариев HTML 53 Исторически сложилось так, что пропуск атрибута language приводит к ин- терпретации сценария как программы на JavaScript. Рекомендуется всегда указывать атрибут language, в соответствии с контекстом сценария документа. ( Примечание ) В HTML 4.0 атрибут language элемента Script использовать не рекомендует- ся. Вместо него следует использовать атрибут type. Атрибут Til Е использует тип MIME для определенного языка для JavaScript используется параметр text/JavaScript, а для VBScript — параметр text/VBScript. Однако посколь- ку примитивные браузеры не распознают атрибут TYPE, то рекомендуется ис- пользовать тег language или оба тега: language и туре. Обратите внимание, что если распознается атрибут type, то установка атрибута IANGUAGE отменя- ется. С введением Netscape Navigator 3.0 компания Netscape начдив присоединять номер версии к строке определения языка JavaScript. Полому для написа- ния программы, которая выполняется только в Netscape 3.0 и Microsoft Internet Explorer 4.0 или более поздней версии, установите значение атрибу- та language равным JavaScript I. /. Данный метод работает, поскольку если браузер не распознает указанный язык, то программа нс выполняется и блок сценария пропускается. В разделе данной главы "Языки написания сценариев" можно найти программу, которая демонстрирует, как определить поддерживаемые клиентом языки написания сценариев без проверки тина и версии браузера. Сценарии, содержащиеся в элементе scrip:., могут выполнять программу в двух контекстах: в ходе анализа страницы и в результате события. Приве- денный ниже сценарий демонстрирует оба типа программ. Программа, ко- торая включена непосредственно в элемент Script. но отсутствует в функ- ции. выполняется непосредственно после начала анализа. Программа, кото- рая содержится в функции, может выполняться только при вызове функции, непосредственно или вследствие события. События представляют собой уведомления, которые возникают когда поль- зователь взаимодействует со страницей или когда изменяется состояние до- кумента — например, когда пользователь нажимает документ или документ изменяется. Модель событий подробно описана в главе 3. <HTML> <HEAD> <TXTLE> Execution of Code </TITLE> <SCRIPT LANGUAGE= "JavaScript"> // Приведенное ниже сообщение появляется во время загрузки странишл. alert('Hello, World!'); function helioWorld() ( // Данная программа выполняется только при вызове функции helloWorld.
54 Часть I. HTML и программирование сценариев alert('Hello, World Too!'); ) </SCRIPT> </HEAD> </HTML> Библиотеки сценариев Сценарии могут находиться но внешнем файле и быть связаны с любым ко- личеством HTML-документов. Это обусловлено несколькими причинами, наиболее очевидной из которых является необходимость написания общих библиотек сценариев, которые будут использованы многочисленными стра- ницами. В зависимости от браузера данные страницы сценариев могут быть кэшированы, что увеличивает производительность, поскольку общие функ- ции не требуется записывать на каждую страницу. Другая причина заключа- ется в способе создания страницы. Если сценарии и содержание страницы написаны разными авторами, то обоим авторам не требуется одновремен- ный доступ к одному файлу. Автор сценария может написать сценарий в одном файле, а автор содержания может поместить содержание в другой файл. Это согласуется с принципом разделения представления и содержа- ния, поддерживаемым таблицами стилен. Ссылка па внешний сценарий осуществляется с помощью атрибута нас, как показано в приведенном ниже примере: <SCRIPT LANGUAGE™ "JavaScript” SRC™ "genericFile.js"> /★ Здесь можно поместить текст программы для браузеров, которые не поддерживают атрибут SRC.*/ // Всегда указывайте закрывающий тег SCRIPT. </SCRIPT> Даже при указании атрибута src тег <script> должен иметь закрывающий тег. Браузеры, не поддерживающие атрибут src. игнорирую! содержание элемента script. Браузеры, которые распознаю! атрибут src, интерпретиру- ют содержание элемента script как программу. Поддержка внешнего файла сценария доступна только в Netscape Naviga- tor 3.0 и Internet Explorer 4.0 или более поздней версии. Поэтому при ис- пользовании внешних файлов сценариев учтите ограниченные возможности более ранних версий данных браузеров. Немедленное выполнение программы Как упоминалось выше, динамический HTML позволяет создавать про- грамму, выполняемую в ходе анализа страницы*. Данная программа создает- ся за пределами области действия обработчиков событий, процедур или функций. Подобная программа служит двум главным целям:
Гпава 2. Основы сценариев HTML 55 П Добавлению свойств в объект window и инициализации его состояния □ Выводу содержимого в поток документа Первая цель сходна с описанием того, что можно считать глобальными пе- ременными. Во всех языках написания сценариев переменные, которые ог- раничены объектом window, добавляются непосредственно в объект window как свойства. В приведенном ниже примере переменная х добавляется как свойство в окно: <SCRIPT LANGUAGE» "JavaScript"> var x=0; //Создает свойство и присваивает ему значение, равное 0. alert(window.х); //Выводит 0, значение переменной х. </SCRIРТ> Чтобы лучше разобраться в приведенной выше программе, рассмотрим бо- лее подробный пример: <SCRIPT LANGUAGE» "JavaScript"> //Создает свойство х и присваивает ему значение, равное 10. var х = 10; function foo() ( //Данная программа выполняется только после явного вызова. /* Создает экземпляр переменной у, который существует только во время выполнения функции.*/ var у = 0; alert(х); //Выводит 10; х является свойством окна. I //Вызывает foo при загрузке страницы. foo() ; window.foo(); //Вызывает функцию foo снова, поскольку данная функция добавляется в окно. </SCRIPT> Данная программа демонстрирует, что выполнение программы и функций может быть попеременным. Программа, которая вызывает функцию при загрузке страницы, должна содержать описание этой функции. Второй целью программы, которая выполняется при загрузке страницы, яв- ляется запись содержимого в документ. Это выполняется с помощью метода write объекта document. Ниже приведена простая программа, которая запи- сывает строку "Hello, World!" в HTML-документ: <HTML> <HEAD> <TITLE>Heilo, World!</TlTLE> </HEAD> <BODY>
56 Часть I. HTML и программирование сценариев <SCRIPT LANGUAGE’ "JavaScript"> //Запись строки "Hello, World!" в документ, document.write("<Hl>Hello, World!</Hl>") </SCRIPT> </BODY> </HTML> Метод write может быть вызван в ходе загрузки страницы для вставки со- держимого для манипулирования. Чтобы изменить содержание после за- грузки страницы, следует использовать другой метод. Динамическое добавление содержания в документ в ходе процесса загрузки обсуждается в главе 6, а манипулирование содержанием обсуждается в главе 13. Местоположение сценариев в документе Документ может содержать неограниченное число элементов script. Эле- мент script может находиться в заголовке или теле документа. В большин- стве случаев местоположение сценария не имеет значения для дизайна страницы. Однако сценарии, которые выполняют инициализацию, обычно помешаются в заголовке документа. Местоположение элемента script более важно, если элемент действительно записывает содержание в поток документа или ссылается на элемент в до- кументе. Запись в поток осуществляется с помощью методов write или writein в объекте document, как показано в приведенном ниже примере: <HTML> <SCRIPT LANGUAGE’ "JavaScript"> // Генерирует весь документ на основе данного сценария, document.write("<HEADxTITLE>My Document</TITLEX/HEAD>"); document.write("<BODY><Hl>This is my page. </iIlx/BODY>") ; </SCRIPT> </HTML> Данный код создает и воспроизводит следующий HTML: <HTML> <HEAD> <TITLE> Мой документ </TITLE> </HEAD> <BODY> <H1>Это моя страница.</И1> </BODY> </HTML> Если вы записываете содержание заголовка, то важно поместить сценарий в заголовке. Например, сценарий, помещенный в середине страницы, нс бу-
Гпава 2. Основы сценариев HTML 57 дет выводить текст HTML, который устанавливает заголовок документа. При вызове методов write или writein содержание документа помещается в поток в текущем месте. Например, вставка тега <title> в неверном месте может изменить определение типа документа (DTD) HTML и привести к непредсказуемым последствиям. Использование методов wri te подробно обсуждается в главе 6. Генерация страниц с помощью метода document.write не всегда является идеальным способом, поскольку препятствует работе инструментов редакти- рования и индексирования, которые не смогут интерпретировать сценарии. Без выполнения сценария в фоновом режиме действительное содержание останется неизвестным. Доступность объектов Следует аккуратно позиционировать сценарии, которые выполняются в ходе анализа страницы и которые ссылаются на элементы на странице. Для дан- ных сценариев доступны только те элементы, которые были ранее загруже- ны, поскольку опережающее описание элементов невозможно. То же самое справедливо для любых функций или переменных, которые могут быть вы- званы — они должны быть всегда определены, прежде чем они могут быть вызваны. Попытка доступа к элементам в исходном коде HTML, который размещает- ся после элемента script, в ходе немедленного выполнения программы приведет к генерации ошибки. Например, сценарии, которые выполняются в заголовке документа при загрузке страницы, не могут ссылаться на формы или другие элементы, которые находятся в теле документа. Данное правило справедливо только для сценариев, которые выполняются в ходе загрузки страницы. Сценарии, выполняемые в ответ на события, не- обязательно должны находиться после элемента, па который дается ссылка. После окончания анализа документа все параметры документа считаются полностью доступными. Однако возможен вызов обработчиков событий прежде, чем документ будет полностью загружен. Перед созданием ссылки на элемент, который может быть еще не загружен, необходимо проверить наличие данного элемента: <SCRIPT FOR= "document" EVENT= "onclickf) LANGUAGE= "JavaScript"> //Данная программа выполняется только когда пользователь щелкает мышью в документе. //Проверка наличия элемента. if (null !=document.all.myElement) { //Некоторые действия.
58 Часть I. HTML и программирование сценариев else alert("Документ загружен не полностью!"); </SCRIPT> Связывание событий обсуждается в главе 3. Отложенное выполнение сценария Internet Explorer 4.0 может повысить производительность выполнения сце- нариев, которые не содержат немедленно выполняемого кода. Если элемент Script содержит только описания функций, то помещение атрибута defer в тег <script> уведомляет браузер, что не требуется ожидать окончания ана- лиза и интерпретации всего сценария. Вместо этого браузер может продол- жать загрузку и отображение страницы. Данный атрибут должен быть ис- пользован только в том случае, если элемент Script не содержит ничего, кроме описаний функции и когда все последующие сценарии, которые вы- полняются немедленно, не вызывают данные функции. Немедленно выпол- няемый код в элементе script может отреагировать непредсказуемо. При правильном использовании атрибут defer не вызывает отрицательного влияния на браузеры, которые нс распознают данный атрибут. Примитив- ные браузеры игнорируют его и выполняют традиционное блокирование до тех пор, пока нс закопчен анализ сценария. Языки написания сценариев Подобно возможности определения многочисленных элементов Script оди- ночный документ может также содержать и выполнять программы на раз- личных языках написания сценариев. Все доступные в настоящее время языки написания сценариев будут выполняться на странице, если браузер поддерживает их. Например, при использовании Internet Explorer страница может быть создана с помощью программ на JavaScript и VBScript. Более того, допускается вызов функций из программы на одном языке програм- мой, написанной на другом языке, как продемонстрировано в приведенном ниже коде. Вызов функции в сценарии па другом языке возможен, посколь- ку все функции и переменные добавляются как методы и свойства объекта window. <SCRIPT LANGUAGE» "VBScript"> 'Простая процедура, которая выводит всплывающее окно сообщения, sub MyAlert(str) msgBox(str) end sub </SCRIPT> <SCRIPT LANGUAGE» "JavaScript">
Гпава 2. Основы сценариев HTML 59 // Вызов процедуры VBScript по имени MyAlert, определенной выше. MyAlert("Hello, World!"); window.MyAlert("MyAlert является методом объекта окна."); </SCRIPT> Возможность совместного использования различных языков написания сце- нариев позволяет применять простой метод определения языков, которые поддерживает браузер. Приведенный ниже код демонстрирует данный метод: «SCRIPT LANGUAGE= "JavaScriptl. 1"> window.jsll = true; // Установка флага для JavaScript 1.1. // — > </SCRIPT> «SCRIPT LANGUAGE= "VBScript"> <i __ vbSupport = True 'Установка флага для VBScript. </SCRIPT> «SCRIPT LANGUAGE= "JavaScript"> <i — — ><Н1>Ваш браузер не поддерживает сценарии. </Н1> <! — /* В данном примере JavaScript считается самым низким общим знаменателем. Данный пример может быть модифицирован для использования другого языка для окончательного тестирования.*/ document.write("Поддерживается язык JavaScript.<BR>"); if (null (-^window, jsll) document.write("Поддерживается язык JavaScript 1.1.<BR>"); if (null !=window.vbSupport) document.write("Поддерживается язык VBScript. <BR>"); // — > </SCRIPT> Скрытие сценариев от браузеров низкого уровня Если вы не предпримете меры предосторожности, то браузеры, которые нс поддерживают сценарии, будут воспроизводить код сценариев как часть со- держания документа. Это происходит по причине того, что браузеры низ- кого уровня будут игнорировать тег <script> и обрабатывать содержание как текст HTML. Такое поведение согласуется с методом обработки нерас- познаваемых тегов в HTML и необходимо в эволюции HTML. Для скрытия сценариев от браузеров низкого уровня создайте комментарий HTML, кото- рый охватывает код: «SCRIPT LANGUAGE= "VBScript"> <! — 'Код VBScript
60 Часть I. HTML и программирование сценариев 'На следующей строке заканчивается комментарий HTML. </SCRIPT> <SCRIPT LANGUAGE= "JavaScript"> <! — //Код JavaScript // — > </SCRIPT> Оба языка интерпретируют строку HTML, которая начинается с < как комментарий на одной строке, так что строка игнорируется анализатором языка. Закрывающему комментарию должен предшествовать определенный указатель комментария ('в VBScript, //в JavaScript). Это приведет к тому, что код внутри элемента Script будет обрабатываться как комментарий и не будет воспроизводиться браузерами низкого уровня. При использовании схемы комментариев следует тщательно следить, чтобы не поместить разделитель, открывающий или закрывающий комментарий в строках кода. Если вывод строки обязателен, то разделите ее на несколько частей: <SCRIPT LANGUAGE= "JavaScript"> <! — /* Тег закрытия комментария, который записан в документе, разделен на две строки./ document.write (”<” +”! — Это комментарий, который должен быть записан н" + "потоке. — " + ”>"); // — > </SCRIPT> Использование тегов комментариев HTML внутри сценария скрывает сце- нарий от браузеров низкого уровня, но нс предупреждает пользователя о том, что в странице используются сценарии. Поэтому для указания текста браузеру, который не поддерживает сценарии, используется специальный тег <noscript>. Содержание элемента NoScript игнорируется браузерами, которые поддерживают сценарии: <! —Текст для браузером, которые не поддерживают сценарии -- > <NOSCRIPT> <Н1>Данная страница требует поддержки сценарием. </Н1> <Н2>Пожалуйста, загрузите последнюю версию Internet Explorer для правильного отображения данной страницы. </Н2> </NOSCRIPT> Этот метод работает в браузерах низкого уровня, поскольку они игнорируют тег <noscrift> так же, как тег - script;- за пределами документа. Поддержи- вающий сценарии браузер знает, что не следует воспроизводить содержание между тегами <noscript> и </ncscript>.
Гпава 2. Основы сценариев HTML 61 Пользователь браузера, поддерживающего сценарии, может отключить под- держку сценариев. В этом случае браузер ведет себя как браузер низкого уровня и выводит содержание элемента NoScript. Internet Explorer 4.0 позволяет отключать сценарии посредством установок безопасности. Internet Explorer 4.0 использует мощную модель безопасности, которая может быть настроена для различных "зон" содержания Web. Зона представляет весь Web, корпоративную сеть (intranet) или определенный на- бор страниц. Перечисленные ниже действия позволяют отключить поддерж- ку сценариев для определенной зоны: 1. В меню View выберите пункт Internet Options для отображения диалого- вого окна Internet Options. 2. Выберите вкладку Security из списка страниц. 3. Выберите зону для настройки. Установите переключатель Custom и на- жмите кнопку Settings. 4. В категории Scripting, подкатегория Active Scripting установите опцию Disable. 5. Нажмите кнопку ОК или Apply для сохранения данных установок. Netscape Navigator 2.0 не поддерживает тег <noscript>. Следует использовать другой метод для предупреждения пользователя, что на странице использу- ются сценарии. Данный метод включает в себя написание примитивного сценария в документе, который использует возможности схемы коммента- риев для вывода содержания на клиентах низкого уровня: <! — Другой метод для вывода содержания низкого уровня — > <SCRIPT LANGUAGE= "JavaScript"? <i — — > заш браузер не распознает сценарии. <! — //Текст вашей программы. </SCRIPT? Метод комментариев имеет следующий недостаток: когда вы отключаете поддержку сценариев, содержание элемента Script игнорируется, и отобра- жается содержание элемента NoScript. Поэтому текст комментариев не ото- бражается при отключении сценариев. Хотя метод Noscript используется для браузеров, которые не поддерживают сценарии, данный метод не различает реализации поставщиков. Разные по- ставщики по мере развития динамического HTML будут реализовывать его различные версии. Сценарий может не запускаться в некоторых браузерах. К сожалению, отсутствует простое решение этой проблемы. Некоторые раз- работчики предпочитают создавать многочисленные экземпляры страниц и отправлять разные страницы разным браузерам. Данная переадресация мо-
62 Часть I. HTML и программирование сценариев жет быть выполнена на клиенте. Пример подобной переадресации представ- лен в следующем разделе. ( Примечание Чтобы подчеркнуть возможности динамического HTML, в данной книге боль- шинство примеров кода не содержат меры для браузеров низкого уровня. Переадресация на стороне клиента Одним из методов обработки различных версий про>раммного обеспечения является переадресация пользователя на другие страницы, в соответствии с типом клиентского браузера, как показано в приведенном ниже коде. Пере- адресация на клиентской стороне (client-side redirection) возникает, когда сценарий страницы переключает браузер на другой документ. Путем необя- зательной проверки версии браузера может быть загружена другая версия страницы. При использовании данного метода базовой будет та страница, которая предназначена для более важной аудитории, поскольку переадреса- ция снижает производительность. При переадресации будут загружены две страницы. sSCRIPT LANGUAGE» "JavaScript"? var MS=navigator.appVersion.indexOf("MSIE”); //Проверка того, что браузером является IE4. window.isIE4=(MS > 0) && (parselnt(navigator.appVersion.substring(MS+ 5, MS+6))>=4); if (!isIE4) //Если браузер — не IE4, то загружается не динамическая страница. window.location» "downlevelpage.htm”; </SCRIPT> Во избежание снижения производительности при переадресации на клиент- ской стороне можно выполнить проверку на серверной стороне п отправ- лять только правильную страницу. Однако в зависимости от установок сер- вера данный вариант может быть неприемлем. Выбор языка: JavaScript или VBScript Как упоминалось выше, объектная модель динамического HTML нс зависит от языка и может работать со сценариями на любом доступном языке про- граммирования. Поэтому выбор языка зависит от предпочтений разработчи- ка и предполагаемой аудитории читателей страницы. На данный момент существует два основных языка написания сценариев на Web: JavaScript и VBScript. Комитет ЕСМА (European Computer Manufactures
Гпава 2. Основы сценариев HTML 63 Association — европейская ассоциация производителей компьютеров), в со- став которой входят представители компаний Netscape, Microsoft и других поставщиков, утвердил стандартный вариант языка JavaScript. Реализация JScript компании Microsoft в Internet Explorer 4.0 полностью совместима с новым стандартом. Для создания Web-страниц в Internet, которые должны быть выставлены па всеобщее обозрение, JavaScript предоставляет наибольшие возможности, и поддерживается в настоящее время браузерами Netscape и Microsoft. (При этом также предполагается, что ваша программа использует набор элемен- тов, совместно используемых в различных реализациях). Кроме того, синтаксис для управления программным потоком в JavaScript очень сходен с синтаксисом в таких языках, как Java, C++, которые знако- мы многим авторам Web-страниц. Хотя Microsoft и Netscape поддерживают JavaScript, они придерживаются различных стратегий реализации возможностей динамического HTML. По- этому, если требуется обеспечить совместимость с различными браузерами, то проявите осторожность при создании динамических страниц. Ниже пред- ложены методы, которые помогут вам при создании интеллектуальных и совместимых страниц. Для корпоративных сетей, в которых используется только один тип браузе- ра, выбор языка написания сценариев становится второстепенной пробле- мой. В данном случае выбор языка должен быть основан па браузере, кото- рый является стандартом для компании, и тех знаниях, которыми распола- гают авторы Web-страниц. Если разработчики Web хорошо знакомы с Microsoft Visual Basic и установлен браузер Microsoft Internet Explorer, то ра- зумнее использовать VBScript, а не JavaScript. JavaScript В данной книге концепция объектной модели отделена от языка програм- мирования. Однако поскольку без языка программирования динамический HTML будет представлен очень абстрактно, то для ясности в данной книге во всех примерах используется язык JavaScript. Некоторые объекты JavaScript не являются частью объектной модели дина- мического HTML и являются специфическими для языка. Например, тип данных даты, математический, числовой и другие типы данных являются специфическими для языка. В зависимости от языка Moiyr быть использо- ваны различные типы данных. Например. VBScript использует тип данных string (строка), но в VBScript строка не является объектом со своим собст- венным интерфейсом. Напротив, манипуляции со строкой выполняются отдельно, при помощи функций. Приведенный ниже код сравнивает мани- пуляции со строкой свойства title в VBScript и JavaScript:
64 Часть I. HTML и программирование сценариев <! — Простое сравнение функций строки в VBScript и JavaScript — > <SCRIPT LANGUAGE” "VBScript"> dim s 'Описывает строковую переменную. s=document.title 'Инициализирует переменную. msgBox(len < s)> 'Выводит длину s. msgBox(left(s, 1)) 'Выводит первый символ s. </SCRIPT> <SCRIPT LANGUAGE” "JavaScript"> var s ^document.title; //Инициализация переменной во время описания. alert(s.length); //Выводит длину s. alert(s.charAt(0)); //Выводит первый символ s. </SCRIPT> Передовые методы JavaScript В этом разделе приведено описание передовых концепций JavaScript, кото- рые используются в данной книге. Раздел предназначен не для изучения JavaScript, а для знакомства с некоторыми наиболее мощными, но менее известными возможностями языка. Добавление свойств в объекты Массивы и объекты в JavaScript предоставляют два метода доступа к их со- держанию: прямая ссылка на содержание как свойство с помощью точечной (.) нотации или ссылка на индекс в массиве с помощью скобок ((index]). Индекс в массиве JavaScript может быть значением типа string, которое представляет имя свойства. Точечная нотация позволяет осуществлять пря- мой доступ к свойству, когда имя свойства известно заранее. Когда вызы- ваемое свойство должно быть переменной, то к нему можно обрати ться по- средством позднего связывания, используя идентификатор строки: <SCRIPT LANGUAGE” "JavaScript"> var prop = "title"; alert(document.title); //Доступ к названию посредством точечной нотации. а 1ert(document[prop]); //Доступ к свойству, на которое ссылается переменная prop. //Массивы и встроенные объекты работают одинаково. var ar =new Array; ar.myProperty” "Demo"; alert(ar.myProperty); alert(ar["myProperty"]); </SCRIPT> Объекты в JavaScript являются уникальными ио своей способности авю- матического расширения. Вы можете добавить новое свойство в объект.
Гпава 2. Основы сценариев HTML 65 просто назначив ему значение. Платой за это удобство является усложнение отладки. JavaScript является чувствительным к регистру. Например: <SCRIPT IANGUAGE= "JavaScript"» alert(document.title); // Вывод заголовка документа. document.Title= "He является настоящим заголовком"; //Добавление свойства Title. alert(document.Title); //Вывод нового свойства Title. </SCRIPT> В этом примере две инструкции сообщения являются различными. Более того, вторая строка не генерирует ошибок. Элемент Title добавляется как свойство объекта document. Поэтому следует быть осторожным при написа- нии программы JavaScript. Отладка больших сценариев может быть весьма затруднительна. ( Примечание J Internet Explorer 4.0 не чувствителен к регистру. Internet Explorer 3.0 и все вы- пуски Netscape Navigator требуют четкого выполнения правил чувствительности к регистру. Для решения проблем отладки Internet Explorer 4.0 предлагает свойство до- кумента expando, которое может быть использовано для отключения воз- можности неявного добавления свойства в JavaScript, как показано в приве- денном ниже коде: <SCRIPT LANGUAGE» "JavaScript"» /* Internet Explorer 4.0 позволяет отключать возможность неявного добавления свойств.*/ document.expando=false; document.Title» "He является действительным заголовком"; //Ошибка — отсутствует данное свойство </SCRIPT> Свойство expando не отключает явное добавление свойств в окно путем опи- сания переменных, но отключает неявное добавление, как показано в при- веденном ниже примере: <SCRIPT LANGUAGE» "JavaScript"» document.expando=false; var x = 0; //Нет ошибки alert(window.x); //Явно добавляется x window.y=10; //Ошибка — отсутствует свойство у </SCRIPT>
66 Часть I. HTML и программирование сценариев ( Примечание ) Internet Explorer 4.0 является первым браузером, который поддерживает свой- ство expand© для управления связанной характеристикой массивов объектов. Netscape Navigator 4.0 и ранние версии Internet Explorer не распознают данное свойство. Когда свойство expando не распознается, то ссылка на него автома- тически приводит к его добавлению в объект document. Поскольку любой объект может содержать любое число свойств, то Java- Script использует оператор совместимости для доступа к ним. С помощью цикла for...in вы можете выполнить инструкцию для каждого используе- мого свойства в объекте, без выяснения конкретных свойств. Приведенный ниже код выводит все свойства, используемые в объекте window: <SCRIPT LANGUAGE= "JavaScript"? // Отображает сообщение со всеми свойствами окна и их значениями. var sProps= "Window PropertiesXn"; for (props in window) sProps += props + ": " +window(props] + "\n"; alert(sProps); </SCRIPT? Указатели функций Любую функцию можно рассматривать как свойство. Это позволяет дина- мически добавлять функцию как метод, который может быть вызван или динамически связан с обработчиком событий. Указатели функций (function pointers) являются очень мощными в том смыс- ле, что они позволяют повторно использовать функции как методы объекта, как показано в приведенном ниже примере: <SCRIPT LANGUAGE= "JavaScript"? //Определение функции test. function test() { alert("Функция была вызвана"); ) // Функция test как обработчик нажатия кнопки. //Это приводит к тому, что при щелчке мышью в документе вызывается функция test. document.onclick= test; </SCRIPT? Кроме того, при вызове функция имеет доступ к массиву arguments, кото- рый содержит все параметры, передаваемые функции. JavaScript автоматиче- ски заполняет массив arguments в момент вызова функции. Приведенный ниже код демонстрирует, как функция может вызвать массив arguments:
Гпава 2. Основы сценариев HTML 67 <SCRIPT LANGUAGE» "JavaScript"» function testArgsO { /* Функция в JavaScript может обращаться к массиву аргументов. Данный массив содержит все параметры, которые передаются функции. */ alert(arguments.length + "arguments"); //Вывод числа аргументов. //Вывод каждого аргумента. for (var i=0; i <arguments.length; i++) alert("argument " + i +" — " + arguments[i]); ) testArgs(l, 2, 3, 4); //Вызов функции testArgs с четырьмя аргументами. </SCRIPT» Массив arguments позволяет написать функцию, которой может быть пере- дан ряд переменных аргументов. На основе передаваемых аргументов могут выполняться различные действия. Простой демонстрацией использования данной возможности является процедура суммирования: <SCRIPT LANGUAGE» "JavaScript"» function Sum() //Суммирует все передаваемые аргументы и возвращает результат, var intSum = 0; for (var intLoop = 0; intLoop <arguments.length; intLoop++) intSum += arguments[intLoop]; return intSum; ) alert(Sum(1, 1, 1, 2)); //Добавляет четыре значения. </SCRIPT> Функции могут быть также созданы динамически с помощью оператора new. Функция создается следующим образом: var functionname = new Function(argsl, ... argsn, body); Может быть указано любое число аргументов args, включая 0. Последним аргументом конструктора Function всегда является выполняемый код. На- пример, приведенный ниже код создает простую функцию, которая возвра- щает разницу между двумя числами: var Difference = new Function("x”, "у", "return x - y;”); Данный пример надуман, так как будет проще выполнить эту операцию не- посредственно или инкапсулировать код в реальную функцию. Смысл дан- ного кода заключается в том, что может быть создана и уличена временная функция, то есть код предоставляет простой "способ динамического созда- ния функции. Создание функций для динамического создания обработчиков событий продемонстрировано в нескольких примерах данной книги.
68 Часть I. HTML и программирование сценариев Проверка поддержки JavaScript предоставляет гибкий метод проверки, поддерживается ли опреде- ленное свойство или метод данным браузером. Метод может быть использо- ван для прогнозирования успешного выполнения кода и для запуска другого кода, если данный элемент отсутствует. Например, приведенный ниже код проверяет поддержку семейства ail в документе: <SCRIPT LANGUAGE» "JavaScript"> if (null == document.all) { // Семейство all не поддерживается, запускается альтернативный код. ) else { //Операции с семейством all. ) </SCRIPT> Соглашения об именовании свойств и функций Способность добавления переменных и функций в Любой объект в JavaScript является очень мошной. Однако данная возможность увеличивает риск по мере развития динамического HTML. При каждом динамическом добавле- нии разработчиком свойства в объект возникает опасность потенциального конфликта между свойством и будущими изменениями в объектной модели. Ниже приведены некоторые указания, которые позволят снизить риск воз- никновения конфликтов в будущем: □ Начинайте имена переменных с заглавной буквы, указав перед ней пре- фикс с типом данных или в виде знака подчеркивания (например, Counter, intCounter ИЛИ _counter). □ Не используйте имя тега в качестве имени переменной, независимо от регистра. Это позволит предотвратить конфликт с элементами, которые используют или могут использовать конструкцию new (например, new Image). □ Не следует использовать в качестве префикса в имени переменной или функции слова html, css или style. Данные префиксы могут иметь .более широкое использование в будущем. Возможно, лучшим методом предотвращения конфликтов является добавле- ние только объектов с одним членом во встроенные объекты и затем добав- ление всех новых индивидуальных членов в данный объект. Такой метод изолирует потенциальный конфликт с одним свойством, но требует некото- рых мер предосторожности: необходимо определить одиночное свойство для того, чтобы в коде не возникали синтаксические ошибки. Ниже приведен
Гпава 2. Основы сценариев HTML 69 пример использования данного метода с объектом window, в котором все ин- дивидуальные члены добавляются в свойство Custom: <SCRIPT LANGUAGE= ”JavaScript"> //До использования объекта —Custom инициализируйте его как свойство объекта window. if (null == window.—Custom) window.—Custom=new Object; // Добавление свойств в —Custom, window.—Custom.special=true; window._Custom.top=self; </SCRIPT> Инструкция инициализации должна предшествовать добавлению свойств в объект -Custom, поскольку JavaScript может добавлять в объект только один элемент одновременно. Если объект Custom не был сначала инициализиро- ван, то при обращении к свойству special возникнет ошибка. Сценарии и безопасность в Web С введением сценариев осложнился вопрос с безопасностью в Internet. В настоящее время браузеры могут создавать sandbox (песочницу) вокруг страницы со сценарием, так что доступ возможен только к правильно опре- деленному набору информации. В динамическом HTML для доступа к ма- шине и жесткому диску клиента используется хорошо управляемый меха- низм cookies. Механизм cookies будет рассмотрен в главе 6. Даже без доступа к компьютеру пользователя доступ к содержанию и мани- пулирование страницей может представлять опасность. Например, страница за пределами брандмауэра не должна иметь доступа к содержанию страни- цы, которая находится под защитой брандмауэра. Несанкционированная страница могла бы обратиться к тексту на странице и отправить его обратно на сервер. Модель "песочницы" (sandbox) требует, чтобы страницы поступа- ли из одного домена до разрешения неограниченного доступа к содержа- нию. Такой механизм предотвращает доступ документа из одного фрейма к документу из другого фрейма, если документы поступают с различных узлов. Для большей гарантии безопасности объектная модель ограничена в ряде случаев. Например, обьект загрузки файлов позволяет пользователю загру- жать файлы па сервер. Чтобы исключить доступ страницы к файловой сис- теме пользователя, значение свойства value, представляющее загружаемый файл, должно быть установлено равным read-only (только чтение). Объект history, который позволяет создавать кнопки Forward (Вперед) и Back
70 Часть I. HTML и программирование сценариев (Назад), не использует информацию об отображаемой ссылке URL. Допол- нительные ограничения безопасности описываются ниже. Для тех пользователей, которые особенно озабочены вопросами безопасно- сти, браузеры позволяют включать и отключать поддержку различных эле- ментов, включая апплеты Java и элементы управления ActiveX, cookies и да- же поддержку сценариев. Объектная модель может получить доступ к огра- ниченной информации, которая помогает ей определить состояние браузера и выработать соответствующую реакцию.
Глава 3 Модель событий динамического HTML События (events) представляют собой извещения, которые генерируются в результате действий пользователя или изменения состояния документа или окна. Динамический HTML предоставляет набор событий, позволяющих Web-мастеру определять реакцию на большую часть взаимодействий между пользователем и документом. Определяя реакцию на события, автор может создавать полностью интерактивные страницы. В данной главе будут рассмотрены методы обработки событий. Глава закан- чивается демонстрацией приложения, которое объединяет элементы встро- енной поддержки динамического HTML с возможностями указателей функ- ций JavaScript для создания механизма связывания событий. В главе рассмотрены следующие темы: □ Общая модель событий. Динамический HTML предоставляет мощную модель событий, которая тесно связана с основной структурой докумен- та. Понимание модели и использование ее преимуществ позволит вам создавать эффективные и поддерживаемые программные продукты. Мо- дель событий динамического HTML основана на двух новых мощных элементах, служащих для управления поведением документа: "всплывание" событии (event bubbling) и действия по умолчанию (default actions). Всплывание событий является элементом модели событий, который обеспечивает просмотр структурной иерархии документа при обработке извещений событий. На любое событие может быть получена реакция от всех родительских элементов в иерархии контейнеров, а также от элемен- та, в котором возникло событие. Другими словами, каждое действие, происходящее в элементе, его родительском элементе и так далее вплоть до тела документа, и в конце концов — самого документа, получает из- вещение события. Событие может быть обработано на любом уровне, что позволяет создавать компактные настраиваемые программы.
72 Часть I. HTML и программирование сценариев Действия по умолчанию обеспечивают встроенную в браузеры обработку события. Многие события позволяют заменять действия по умолчанию на индивидуальную обработку или добавлять дополнительные процедуры обработки. Понимание модели событий совершенно необходимо для правильного использования мощи динамического HTML с целью создания интерак- тивных документов. В данном разделе представлена архитектура событий. В последующих главах будут подробно рассмотрены методы и операции. □ Связывание событий. Связывание событий (event binding) является созда- нием связи сценария с событием в документе или окне, или с событием в элементе данного документа. В данном разделе обсуждаются различ- ные доступные в динамическом HTML методы для связывания сценариев с событиями. □ Объект event. Объект event представляет информацию, связанную с со- бытием в сценарии. Объект event представляет собой независимый от языка механизм для передачи параметров и для управления различными аспектами модели событий. Например, для события мыши, информация о текущем положении мыши и состоянии кнопки представлена свойст- вами объекта event. □ Программирование стандартных пользовательских событий. Стандартные пользовательские события включают в себя события мыши, клавиатуры, фокуса и события помощи, которые доступны почти в каждом элементе документа. В данном разделе вводятся взаимоотношения между данными событиями и объектом event. Дополнительные события, которые под- держиваются соответствующими элементами и объектами, обсуждаются на протяжении всей книги вместе с их объектами. □ Примеры событий. Глава завершается двумя примерами связывания собы- тий. Первый пример называется Event Tntoi (Изучение событий), кото- рый может быть использован /мы изучения модели событий. В данном примере события в документе можно отслеживать индивидуально или как группу. Второй пример, Event Broadcaster (Транслятор событий), яв- ляется мощной демонстрацией работы указателей функций и собызпй JavaScript. В этом примере вы узнаете о том, как разработать индивиду- альный механизм связывания событий, который позволяет легко связы- вать многочисленные функции с одним событием. Общая модель событий При взаимодействии пользователя со страницей или во время изменения состояния документа происходят события. Пользователь генерирует события при передвижении мыши, нажатии кнопок мыши или вводе с клавиатуры текста в документе. Изменения состояния документа, которые могут вызвать генерацию событий, включают в себя загрузку документа, изображений или
Гпава 3. Модель событий динамического HTML 73 объектов, появление ошибки на странице и переход фокуса от одного эле- мента к другому. Всплывание событий HTML-документы представляют собой структурированные документы с оп- ределенной иерархией контейнеров. Всплывание событий представляет со- бой родовое свойство всех действий, которые перемещаются по данной структурной иерархии. После возникновения событие сначала появляется в исходном элементе, затем в родительском элементе источника события и продолжает возникать в родительских элементах до тех пор, пока не дойдет до элемента документа. Всплывание событий отсутствовало в ранних версиях объектной модели HTML, поскольку тогда оно не требовалось. В прошлом разработчики брау- зеров рассматривали лишь несколько элементов, которые могли генериро- вать события. В динамическом HTML все элементы генерируют события. Это значит, что теперь все элементы на странице — каждый тег р, hi и так далее — нс только могут, но и генерируют события. Переход к генерации событий всеми элементами мог бы сильно усложнить сценарии. Но с появ- лением всплывания событий сценарии стали более мощными и их стало проще писать. В приведенном ниже коде тело документа, ссылка и изображение имеют связанные с ними события: <HTML> <HEAD> <TITLE> Иди домой! </TITLE> . </HEAD> <BODY> <A HREF= "home.htm">IMG SRC = "home.gif"> Иди домой</А> </BODY> </HTML> Без всплывания событий код обработчика событий для всех событий нажа- тия кнопки, которые происходят на ссылке, был бы очень сложным. Дан- ный обработчик событии требовалось бы написать дважды: один раз для изображения и второй раз для ссылки. Такая избыточность была бы необхо- дима, поскольку если пользователь щелкает мышью по изображению, то изображение получает событие, и если пользователь щелкает по тексту ниже изображения, то ссылка получает событие. Применение всплывания собы- тий решает данную проблему. При использовании всплывания событий на- жатие кнопки мыши сначала на изображении приводит к генерации собы- тия для изображения. Затем автоматически событие генерируется для ссыл- ки. После чего событие возникает в теле документа и, наконец, в самом документе. Всплывание событий позволяет обрабатывать событие на каждом
74 Часть I. HTML и программирование сценариев уровне иерархии контейнеров. В приведенном выше примере кода один об- работчик событий нажатий кнопки на ссылке будет также обрабатывать щелчки мышью по изображению. Действия по умолчанию Помимо всплывания событий многие события имеют действия по умолча- нию. Действие по умолчанию является действием, которое браузер выпол- няет в ответ на событие. Например, действием по умолчанию в ответ на на- жатие ссылки <а href» является переход по указанному адресу и загрузка страницы. В объектной модели динамического HTML можно заменять существующие действия по умолчанию на индивидуальную модель поведения. Если собы- тие не имеет действия по умолчанию и создастся индивидуальная модель поведения, то рекомендуется отменить возможное действие по умолчанию. Это гарантирует правильное выполнение программы, если действие по умолчанию будет позднее поддерживаться браузером. Действие по умолчанию не всегда определяется источником события — оно может определяться родительским элементом. В приведенном выше приме- ре, когда пользователь нажимает кнопку мыши на изображении, действие по умолчанию по переходу к указанной ссылке определяется элементом Anchor (ссылка), который содержит изображение. Однако если изображение отменяет действие по умолчанию для события, то действие по умолчанию для данной ссылки больше не будет действовать, поскольку действие по умолчанию может быть отменено любым элементом в цепочке событий. По- сле того как обработчик событий устанавливает отмену действия по умолча- нию, оно отменяется для всей цепочки событий. Всплывание событий и действия по умолчанию представляют собой различ- ные концепции, которыми можно управлять независимо. Например, если изображение останавливает событие в момент всплывания к ссылке, но не отменяет действие по умолчанию, то действие по умолчанию для ссылки будет применено к событию и будет осуществлен переход по ссылке. Образ- ное также справедливо: если ни ссылка, ни изображение не отменят дейст- вие по умолчанию, но действие по умолчанию отменяется, когда событие достигает элемента Body, то переход по ссылке не будет осуществлен. Свой- ства для отмены действия по умолчанию или остановке всплывания события описаны в разделе "Объект event' ниже в данной главе. Связывание событий Связывание событий представляет собой создание связи между определен- ным событием и сценарием. Динамический HTML поддерживает ряд неза- висимых от языка методов по связыванию сценариев с событиями. Кроме
Глава 3. Модель событий динамического HTML 75 того, процессоры сценариев сами по себе могут использовать другие инди- видуальные способы поддержки связывания событий. Независимые от языка механизмы связывают события посредством атрибу- тов элемента Script, посредством специальных атрибутов HTML, связанных непосредственно с определенным элементом или посредством объектной модели. VBScript также предлагает механизм связывания в стиле Visual Basic, который включает в себя установку имен подпроцедур обработчика опреде- ленным способом. Атрибуты событий В динамическом HTML все элементы документа были изменены для под- держки событий клавиатуры и мыши. Данные события представлены как атрибуты непосредственно для каждого элемента, что позволяет устанавли- вать прямую связь между элементом и его поведением. Данная связь сходна со связью между элементом и встроенным стилем при использовании атри- бута style. Например, можно связать событие onclick (нажатие кнопки) с функцией с помощью атрибута, как показано в приведенном ниже примере: <! — Когда пользователь щелкает по кнопке мыши, вызывается функция food. CINPUT TYPE=BUTTON VALUE» "Нажмите здесь” ONCLICK» ”foo();" LANGUAGE» "JavaScript"> Атрибут onclick может вызвать функцию или немедленно выполнить одну или большее число строк кода. В данном примере, когда пользователь на- жимает кнопку мыши, вызывается процедура foo. Атрибут language опреде- ляет язык, на котором написана программа. Пропуск атрибута language ус- танавливает по умолчанию язык, указанный на первой странице или Java- Script в отсутствие других сценариев. Приведенный ниже пример демонст- рирует две встроенных инструкции, которые выполняются при нажатии пользователем кнопки: <! — При нажатии кнопки мыши отображать сообщение и затем вызвать функцию foo () . — > CINPUT TYPE-BUTTON VALUE» "Нажмите здесь" ONCLICK» "alert('Пользователь нажал здесь.'); food;" LANGUAGE» "JavaScript”> Кнопка сначала выводит окно сообщения, а затем вызывает функцию foo. Все атрибуты HTML являются нечувствительными к регистру, регистр симво- лов нс имеет значения при использовании атрибутов, например onclick, для связывания обработчиков с событиями. Чувствительность к регистру может быть важна, когда используются другие механизмы связывания событий. Свя-
76 Часть I. HTML и программирование сценариев зыванис событий с атрибутами HTML удобно, но имеет ряд недостатков. Первый недостаток заключается в том, что требуется расширять язык HTML каждый раз при изобретении нового события. Например, в приведенном вы- ше примере событие onciick подразумевает расширение определения типа документа (DTD, document type definition) за счет включения в тег <input> атрибута onclick. Это усложняет добавление событий стандартным способом, поскольку HTML развивается медленно. Более того, объекты или приложе- ния, которые генерируют произвольные события, также требуют расширения языка или представления их собственных методов связывания событий. По- этому данный подход используется только для небольшого набора встроенных событий. Если в страницу внедрен произвольный объект, то его события представлены более общим способом. Поддержка общих событий Второй механизм связывания лишен указанных выше недостатков. Данный механизм использует новые расширения элемента Script — атрибуты for и event — для связывания функций с событиями. Атрибут event ссылается на событие и все параметры, которые ему могут быть переданы. Атрибут for указывает имя или идентификатор (ID) элемента, для которого написано событие. Например, событие onmousemove представлено в документе. Вы мо- жете использовать тег <script> для связывания с данным событием: <SCRIPT FOR= "document" EVENT= "onmousemove(} LANGUAGE’- JavaScript"» // Данный обработчик событий вызывается, когда указатель мыши // перемещается по документу. </SCRIPT> ( Примечание ) JavaScript является чувствительным к регистру для обоих значений атрибутов event и for тега <script>. Следует убедиться, что все имена событий набра- ны в нижнем регистре для встроенных событий и в соответствующем регистре для внедренных объектов. Кроме того, если вы определяете идентификатор (ID) в атрибуте for, вы должны набрать их в точном соответствии с тем, как они набраны в атрибуте id самого элемента. Если событие не возникает, то всегда проверяйте правильность ввода символов и регистра в теге <script>. Следует принять к сведению следующее предостережение относительно приведенного выше синтаксиса. Netscape Navigator игнорирует атрибуты for и event и попытается выполнять программу немедленно. В приведенном ниже коде используется прием для обхода данного ограничения: <SCRIPT LANGUAGE= "JavaScript"» //Предположим, что браузер поддерживает атрибут FOR. var ForSupport=true;
Гпава 3. Модель событий динамического HTML 77 С/SCRIPT» <SCRIPT FOR™ "fakeObject" EVENT™ "foo" LANGUAGE™ "JavaScript"» //Данное событие не существует. // Если атрибуты FOR и EVENT поддерживаются, то данный код не будет //выполняться. ForSupport=f aJ.se; c/SCRIPT» <SCRIPT FOR™ "document" EVENT™ "onmousemove" LANGUAGE™ "JavaScript"» if (ForSupport) { //Код действительного обработчика событий. I else alert("Ваш браузер не поддерживает необходимый синтаксис события."}; </SCRIPT> Для того чтобы гарантировать, что кол сценария не будет выполняться, сле- дует указать, что используется язык JScript. JScript представляет собой реа- лизацию JavaScript компании Microsoft. Поскольку Microsoft Internet Explorer является единственным браузером, который поддерживает JScript, в сценарии нс требуется инструкция if, которая должна быть проигнори- рована Netscape. <SCRIPT FOR™ "document" EVENT™ "onmousemove() "LANGUAGE™ "JScript"» // Данный обработчик событий вызывается, когда указатель мыши // перемещается по документу, если браузер поддерживает ядро языка // JScript. </SCRIPT> ( Примечание При указании имени события скобки необязательны. Например, приведенное выше событие может быть определено как EVENT™ "onmousemove". . Связывание событий в стиле Visual Basic Помимо обсуждавшихся выше методов язык VBScript также поддерживает механизм связывания сценариев с событиями в стиле Visual Basic. Visual Ba- sic традиционно связывает код с событием с помощью специальной про- цедуры. Если процедура написана в формате Visual Basic, то ядро Visual Ba- sic знает, какие события должны быть связаны со сценарием. Например, приведенный ниже код связывает событие onmousemove с событием onclick в документе: <SCRIPT LANGUAGE™ "VBScript"» Sub document_onMouseMove()
78 Часть I. HTML и программирование сценариев 'Обработчик событий для перемещения указателя мыши по документу. End Sub Sub document_onClick() ’Обработчик событий для нажатий кнопки мыши в документе. End Sub </SCRIPT> С Примечание Microsoft Internet Explorer 3.0 также поддерживает приведенный выше синтак- сис в JScript, но данный синтаксис не поддерживается в Netscape Navigator или Internet Explorer 4.0. Поэтому данный метод не следует использовать с JScript. В VBScript преимущество использования данной модели заключается в том, что могут быть написаны многочисленные обработчики событий внутри од- ного блока сценария. Главный недостаток заключается в том, что внешние инструменты не могут просто определить события, которые были написаны для них обработчиками событий. Использование синтаксиса атрибутов год и event элемента script или синтаксиса атрибута встроенных событий HTML дает возможность быстро сканировать документ и определять события, с которыми связан код. Модель связывания в стиле Visual Basic будет распо- знана только специально написанным инструментом. Можно установить связь с одним событием в нескольких языках. В данном случае событие будет возникать во всех языках, но последовательность воз- никновения события будет неопределенной. В целом результаты использо- вания данного метода непредсказуемы. Определение языков написания сценариев в атрибутах событий Вы можете определить различные языки для каждого встроенного атрибута события HTML. Атрибут ianguage, который используется со встроенными атрибутами событий HTML, определяет язык по умолчанию для интерпре- тации кода. Для изменения установленного по умолчанию языка следует указать необходимое яшчепис идентификатора языка в атрибугс события. Формат данного идентификатора приведен ниже: {Element EventNama= "Language :Cod<'"> Идентификатор Language представляет собой независимую от регистра стро- ку, которая определяет язык написания сценариев для программы code. Internet Explorer 4.0 поддерживает следующие языки: JScript. JavaScript. JavaScript 1.1 и VBScript. Языки JScript, JavaScript и JavaScript 1.1 запускают одно ядро языка. Обработчики onclick и onmousedown в приведенном ниже теге <body> определены в различных языках написания сценариев:
Гпава 3. Модель событий динамического HTML 79 <BODY ONCLICK= "JavaScript:dothis(this);" ONMOUSEDOWN™ "VBScript:dothat(me)"> Netscape Navigator не поддерживает указанные языки для значения атрибута события. Netscape Navigator и Internet Explorer поддерживают указанные языки для атрибута href ссылок, что позволяет создать код JavaScript или VBScript, который будет выполняться при щелчке по ссылке. Однако Netscape Navigator распознает только JavaScript и попытается перейти на недействительную страницу, если указаны другие языки. События как свойства Все события также представлены как свойства в объектной модели динами- ческого HTML. Все имена свойств вводятся в нижнем регистре п начинают- ся с префикса on. Цель представления данных событий и свойств событий заключается в активизации событий для динамического связывания с функ- циями во время выполнения. Для всех свойств событий может быть назна- чен указатель функции. Поддержка указателей функций зависит от языка программирования. JavaScript поддерживает указатели функций, но VBScript не поддерживает данные указатели. Поэтому VBScript не может динамически генерировать обработчиков событий. (Однако вы можете использовать код VBScript для назначения функции JavaScript событию). При возникновении события вы- зывается функция, указанная в свойстве. <HTML> <HEAD> <Т1ТЬЕ>Пример указателя функции</Т1ТЬЕ> </HEAD> <BODY> <INPUT TYPE=BUTTON ID= "myButton” VALUE™ "Click here"> <SCRIPT LANGUAGE™ "JavaScript"> //Присоединение указателя функции к myButton. //При нажатии кнопки myButton отображается окно сообщения. document.all.myButton.onclick= new Function("alert('Hello');''); </SCRIPT> </BODY> </HTML> Для назначения указателя функции укажите имя функции прямо в свойстве. <HTML> <HEAD> <Т1ТЬЕ>Назначение указателя функции</Т1ТЬЕ> <SCRIPT LANGUAGE™ "JavaScript">
80 Часть I. HTML и программирование сценариев //Определение функции clicked. function clicked() { alert("Clicked"); } </SCRIPT> </HEAD> <BODY> <INPUT TYPE=BUTTON ID= "myButton" VALUE» "Click here"> <SCRIPT LANGUAGE» "JavaScript"> //Назначение функции clicked обработчику события onclick. document.all.myButton.onclick=clicked; </SCRIPT> </BODY> </HTML> ( Примечание ) При назначении указателя функции используйте только имя функции. Круглые скобки и дополнительные параметры не требуются. Если они будут указаны, то функция будет выполнена. В результате чего свойству будет назначено воз- вращаемое функцией значение, вместо указателя на функцию. Расписание связывания событий Последовательность, в которой обработчики событий связываются с элемен- тами, определяется языком написания сценария. JavaScript подключает со- бытия асинхронно по мерс загрузки страницы. Каждый элемент Script и ат- рибут события подключаются по мере анализа документа. VBScript не свя- зывает события до тех пор, пока вся страница не будет проанализирована, все внешние сценарии загружены и внедренные объекты не начнут загру- жаться. Для JavaScript это значит, что события начнут происходить в ответ на дейст- вия пользователя или другие действия до того, как страница будет целиком загружена. Поэтому следует позаботиться о том, чтобы обработчики собы- тий не пытались обратиться к элементам, которые могут быть еще не загру- жены. Можно написать программу, которая сначала проверяет наличие элемента или, более обобщенно, просто проверяет, что страница целиком проанали- зирована. Проверка того, что страница целиком проанализирована, является простейшим методом и должна работать в различных языках написания сценариев и браузерах: <HTML> <HEAD> <Т1ТЬЕ>Пример анализа</Т1ТЬЕ>
Гпава 3. Модель событий динамического HTML ит <SCRIPT LANGUAGE= "JavaScript"> function doClick!) ( if (isLoaded) { //Запуск обработчика событий. ) else { alert("Пожалуйста, подождите пока документ не будет загружен."); } > </SCRIPT> </HEAD> <BODY> <INPUT TYPE=BUTTON ID- "mylnput" VALUE- "Click here" ONCLICK= "doClick(")> <SCRIPT LANGUAGE= "JavaScript"> // Данный элемент будет последним элементом, который анализируется // в документе. </SCRIPT> </BODY> </HTML> С помощью обработчика событий можно также проверить, была ли страни- ца проанализирована целиком. Два события могут быть использованы для выполнения этой задачи: событие event в окне и событие onreadystatechange в документе. Событие onload возникает, когда документ целиком проанализирован и все элементы загружены. Более мощное собы- тие onreadystatechange в документе, которое поддерживается только в Internet Explorer 4.0, возникает несколько раз по мере того, как документ проходит несколько состояний загрузки и возникает в последний раз, когда документ полностью загружен. События onload и onreadystatechange подробно обсуждаются в главах 4 и 6. Область действия сценариев Все обработчики событий ограничены элементом, с которым связан обра- ботчик. Данный элемент представлен в языке написания сценариев Java- Script с помощью свойства this, а в VBScript с помощью свойства тс. Область действия события необязательно ограничена элементом, который первым сгенерировал событие. Элемент, который первым сгенерировал со- бытие, Представлен СВОЙСТВОМ srcElement В объекте event. Объект event подробно обсуждается в разделе "Объект event" ниже в данной главе.
82 Часть I. HTML и программирование сценариев Управление указателем this Приведенный ниже код демонстрирует три различных способа связывания обработчика с событием. Все три обработчика эквивалентны. CINPUT NAME- "myBtn" TYPE=BUTTON VALUE3 "My Button" ONCLICK3 "alert(this.name);" "LANGUAGE3 "JavaScript"> ИЛИ CSCRIPT FOR3 "myBtn" EVENT3 "onclick()" LANGUAGE3 "JavaScript"> alert(this.name); c/SCRIPT> ИЛИ CSCRIPT LANGUAGE- "JavaScript"> myBtn.onclick3 new Function("alert(this.name)"); c/SCRIPT> В этих примерах элемент this.name возвращает значение элемента myBtn, поскольку ссылка на элемент дается прямо во встроенном коде или сцена- рии. Если требуется сослаться на элемент в процедуре, вызываемой обра- ботчиком событий, то потребуется передать элемент в процедуру с помощью ключевого слова this. Например, приведенный ниже кол отобразит пустую строку вместо текста myBtn, поскольку указатель this в функции г<;о ссыла- ется на саму функцию, вместо элемента, который генерирует событие: CSCRIPT LANGUAGE3 "JavaScript"> function foot) ( //Указатель this не ссылается на кнопку. alert(this.name); ) c/SCRIPT> CINPUT TYPE=BUTTON NAME3 "myBtn" VALUE3 "My Button" ONCLICK3 "foot);" LANGUAGE3 "JavaScript"> Вместо этого вы должны передать ссылку на элемент myBtn в функцию foo, используя ключевое слово this: cSCRIPT LANGUAGE3 "JavaScript"> function foo(b) { // Аргумент b ссылается на кнопку, поскольку она передается // обработчиком событий. alert(b.name); > C/SCRIPT> CINPUT TYPE=BUTTON NAME3 "myBtn" VALUE3 "My Button" ONCLICK3 "foo(this);" LANGUAGE- "JavaScript">
Гпава 3. Модель событий динамического HTML 83 Указатель this также автоматически устанавливается, когда обработчик со- бытий назначается в качестве указателя функции: CHI ID= "myHl"> Это заголовок. </Н1> cSCRIPT LANGUAGE- "JavaScript"> function clickHandler() { //Свойство this указывает на элемент, с которым связан обработчик, alert(this.tagName) I //Указатель функции не должен передавать указатель this. document.all.onclick=clickHandler; c/SCRIPT> Имена во встроенном коде идентифицируются путем поиска членов объект- ной модели в следующем порядке: 1. Все свойства текущего элемента. 2. Все элементы представлены для пространства имен — например, в фор- ме, элементы управления в форме. 3. Свойства элемента, содержащего пространство имен, — например, свой- ства формы для элементов внутри формы. 4. Свойства документа. Разделяемые обработчики событий JavaScript поддерживает создание разделяемого обработчика событий. В JavaScript все элементы, которые совместно используют одно имя, могут также совместно использовать одинаковые обработчики событий с помо- щью атрибутов for и event элемента script: cSCRIPT FOR= "gender" EVENT= "onclickO "LANGUAGE- "JavaScript"> //Данный обработчик событий выполняется при нажатии любого элемента //с именем или идентификатором "ID". c/SCRIPT> CINPUT TYPE= RADIO NAME= "gender" VALUE» "Male"> CINPUT TYPE= RADIO NAME= "gender" VALUE» "Female"> Данный метод работает только в JavaScript. VBScript может запускать обра- ботчика событий таким образом только па основе уникального идентифика- тора id элемента, а не его имени name. Если бы данный код был переписан на VBScript, то потребовалось бы указать уникальные значения идентифика- торов для кнопок-переключателей и написать отдельный обработчик собы- тий для каждой кнопки. Альтернативой VBScript, которая также работает для любого языка напи- сания сценариев, является использование процедуры всплывания событий и отслеживание события, начиная с родительскою контейнера:
Н4 Часть I. HTML и программирование сценариев «SCRIPT FOR= "GenderGroup" EVENT= "onclickO "LANGUAGE- "VBScript"> 'Данный обработчик событий выполняется при нажатии любого элемента в 'блоке GenderGroup. If "gender" = window.event.srcElement.name Then 1 Пользователь нажал кнопку-переключатель. End If </SCRIPT> <DIV ID= "GenderGroup"> «INPUT TYPE= RADIO NAME= "gender" VALUE= "Male"> «INPUT TYPE= RADIO NAME= "gender" VALUE= "Female"> </DIV> Объект event Многие события сами по себе не представляют интереса без дополнитель- ной информации. Например, событие onmousedown бесполезно, если неиз- вестно, какая была нажата кнопка мыши и каково было положение указате- ля мыши в момент нажатия. События клавиатуры бесполезны, если неиз- вестно, какая была нажата клавиша. Динамический HTML представляет независимый от языка механизм досту- па к информации, связанной с событием, и управления всплыванием собы- тия и возникновением действия по умолчанию. Данная информация пред- ставлена посредством объекта event, который является свойством объекта window. До возникновения события объект event инициализируется с учетом теку- щего состояния клавиатуры и мыши. Объект event предоставляет доступ к параметрам события и обеспечиваем контроль всплывания событий и вы- полнения действий по умолчанию. Объект event всегда представляет как минимум набор перечисленных ниже свойств для идентификации элемента, который запустил последовательность событий, и для управления всплыва- нием событий и действием по умолчанию: □ event.srcElement □ event.cancelBubble (3 event.returnvalue Свойство srcElement возвращает элемент, который первым сгенерировал событие. Например, при нажатии изображения home.gif в примере HTML- страницы в начале данной главы изображение является свойством srcEJe- ment по мере того, как событие всплывает через ссылку, тело и документ. Свойство cancelBubbte используется для прекращения всплывания элемента в направлении вверх по иерархии. По умолчанию значение данного свойст- ва равно false и событие всплывает. Установка значения true для данного
Гпава 3. Модель событий динамического HTML 85 свойства останавливает всплывание только текущего экземпляра события, но не препятствует всплыванию последующих событий. Свойство returnvalue используется преимущественно для отмены действия по умолчанию события. Не все события имеют действия по умолчанию. Однако если вы пишете код, который изменяет поведение события, то всегда отменяйте действие по умолчанию так, чтобы если действие по умол- чанию будет добавлено к событию в будущем, то поведение страницы нс изменилось. Для отмены действия по умолчанию для данного свойства должно быть установлено значение false. Свойство returnvalue наиболее часто используется для отмены действия по умолчанию события, но некоторые события используют свойство returnvalue отличным способом. Это снова приводит к разделению всплы- вания событий и действий по умолчанию. ( Примечание ) JavaScript поддерживает возвращение значений непосредственно обработчику событий, используя ключевое слово return. Ключевое слово t et urn обновляет свойство returnvalue объекта event, когда обработчик событий возвращает управление браузеру. Объект event устанавливается для каждой последовательности событий. Поэтому любые назначения объекта event применимы только к экземпляру последовательности событий. При следующем возникновении события объ- ект event сбрасывается. Отмена действия по умолчанию, например, отменя- ет только действие по умолчанию для текущего события, а не для всех по- следующих событий. По этой причине к объекту event должен обращаться обработчик событий, а не код, который выполняется в ходе загрузки стра- ницы. Определение события Объект event представляет тип события посредством свойства type. Свойст- во type возвращает имя события в нижнем регистре без префикса on. На пример, событие onmousedown возвращается как mousedown, событие onclick — как click и так далее. Зная тип события, один обработчик может различать и обрабатывать различные события: function handleEvent() { //Запуск обычного обработчика событий. switch (event.type) { case "click": //Обработка события onclick, break; case "mousedown":
86 Часть I. HTML и программирование сценариев //Обработка события onmousedown. break; ) ) //Присоединяет события к обработчику событий handEvent. document.onclick=handleEvent; document.onmousedown=handleEvent; Доступ к параметрам посредством объекта event Объект event представляет все параметры встроенных событий как свойства. Например, информация о текущем положении указателя мыши доступна для всех событий. Некоторая информация доступна только для определен- ного события. События мыши также обеспечивают доступ к текущему со- стоянию кнопок мыши. Данные параметры инициализируются и обновля- ются до генерации события. Приведенный ниже пример иллюстрирует про- цедуру доступа к параметрам события: <SCRIPT FOR= "document" EVENT= "onmousedown() ”LANGUAGE= "JavaScript"> //Вывод состояния кнопки мыши при ее нажатии. alert("х:" +event.clientX); alert("у:" +cvcnt.clientY) ; alert("button:" +event.button) ; alert("Source Element:" +evcnt.srcElement.tagName); </SCRIPT> Координаты мыши Объект event представляет свойства, которые определяют положение указа- теля мыши на основе различных систем координат. Свойства событий мы- ши перечислены в табл. 3.1. Таблица 3.1. Свойства событий мыши Свойство Описание clientX, clientY Горизонтальные и вертикальные координаты указателя мыши, относительно клиентской области окна offsetX, offsetY Горизонтальные и вертикальные координаты указателя мыши относительно контекста воспроизведения screenX, screenY Горизонтальные и вертикальные координаты указателя мыши относительно экрана
Глава 3. Модель событий динамического HTML 87 На рис. 3.1 проиллюстрированы взаимоотношения между различными коор- динатами. Создание систем координат и контекстов воспроизведения обсуждается в главе 12. Значения данных свойств постоянны в любой последовательности возник- новения событий и данные координаты устанавливаются для всех событий, а не только событий мыши. Q Mouse Coordinates - Microsoft Internet Explorer j j Ей.... £$.. . U'-... f j* ' и ’ .. . Mouse coordinates Absolutely positioned element ,a] Done ) My Corriputa Рис. 3.1. Начала координат указателя мыши объекта evenL в различных системах Информация клавиш и кнопок Свойства объекта event представлены в табл. 3.2 и определяют текущие кла- виши и кнопки мыши, нажатые во время события. Параметр Значение Таблица 3.2. Свойства объекта event button Набор значений, соответствующих нажатым кнопкам мыши: 0 — Кнопки не были нажаты 1 — Была нажата левая кнопка 2 - Была нажата правая кнопка 4 — Была нажата средняя кнопка Параметр button представляет комбинированное состояние всех кнопок мыши. Например, если были нажаты левая и правая кнопка мыши, то параметр button возвращает 3 ctrlKey Логическое значение, указывающее на нажатие клавиши <Ctrl>
88 Часть I. HTML и программирование сценариев Таблица 3.2 (окончание) Параметр Значение altKey Логическое значение, указывающее на нажатие клавиши <АИ> shiftKey Логическое значение, указывающее на нажатие клавиши <Shift> Данные свойства полезны при написании глобального обработчика со- бытий для документа. Используя координаты мыши вместе с методами elementFromPoint ИЛИ rangeFromPoint В документе, МОЖНО проверить поло- жение указателя мыши на определенном элементе или в точке текста: <SCRIPT EVENT= "onkeypress()" FOR= "document" LANGUAGE= "JavaScript”> // Определяет элемент, на котором находится указатель мыши при нажатии // кнопки. II Методы fromPoint основаны на координатах клиента. var e=document.elementFromPoint(event.clientX, event.clientY); if ("Hl" == e.tagName) { // Здесь должны быть указаны операции, которые выполняются при нажа- // тии кнопки, когда указатель мыши находится на элементе Н1. ) </SCRIPT> Программирование стандартных пользовательских событий Стандартные пользовательские события представляют собой набор событий, совместно используемых всеми элементами для реагирования на действия пользователя. Данные события служат для отслеживания мыши и клавиату- ры, передачи фокуса между элементами и прокручивания любой полосы прокрутки. Многие элементы используют события, специально предназна- ченные для выполнения задачи элемента. Например, элементы форм имеют события onsubmit и onreset. Эти дополнительные события вместе с соответствующими элементами обсуждаются в главах 8—10. События мыши Обьектная модель динамического HTML представляет события для отсле- живания различных состояний мыши, включая^(сремешение указателя мы- ши над элементами и нажатие кнопок мыши. В табл. 3.3 перечислены собы- тия мыши.
Гпава 3. Модель событий динамического HTML 89 Таблица 3.3. События мыши Событие Описание onmousedown Была нажата кнопка мыши onmousemove Перемещается или был перемещен указатель мыши onmouseup Была отпущена кнопка мыши onclick Была нажата левая кнопка мыши или вызвано действие по умол- чанию данного элемента ondbldick Была дважды нажата левая кнопка мыши onmouseover Указатель мыши был перемещен в область элемента onmouseout Указатель мыши был выведен из области элемента ondragstart Была запущена операция перетаскивания onselectstart Было инициировано новое выделение элемента с помощью мыши onselcct Был выделен элемент События onclick и ondbldick Событие onclick представляет собой в большей степени семантическое, чем физическое событие. Хотя событие onclick обычно возникает после нажа- тия левой кнопки мыши, оно может также возникнуть в результате дейст- вия, которое имитирует нажатие кнопки. Например, событие onclick возни- кает, когда пользователь нажимает клавишу <Enter> и фокус находится на какой-либо кнопке. Событие ondbldick возникает, когда пользователь два- жды нажимает левую кнопку мыши в течение определенного системой пе- риода времени. При щелчке мышью по элементу событие onclick возникает после генера- ции событий onmousedown и onmouseup. Событие onclick не обязательно должно генерироваться для того же элемента, па котором возникли события onmousedown и onmouseup. Рассмотрим следующий код HTML: <HTML> <HEAD> <TITLE> Правила нажатия </TITLE> </HEAD> <BODY> <Н1>Добро пожаловать на мою домашнюю страницу</Н1> <Н2>Последняя информация о динамическом НТМЕ</Н2> <BODY> </HTML>
90 Часть I. HTML и программирование сценариев Если кнопка мыши была нажата, когда указатель мыши находился на эле- менте Н1, то для данного элемента возникают события onmousedown, onmouseup и onclick. Если кнопка мыши была нажата на элементе hi и от- пущена на элементе Н2, то событие onmousedown возникает для элемента hi, а событие onmouseup возникает для элемента Н2. Событие onclick возникает в теле документа как любое последовательное событие ondbiciick, которое может возникнуть как часть данной последовательности, поскольку тело является общим элементом, на котором находится указатель мыши при от- пускании кнопки мыши. Событие onmouseup возникает па элементе Н2, а не на элементе in, поскольку мышь установлена на текстовом элементе. Элементы HTML, которые требуют ввода информации пользователем, захватывают событие мыши. Если кнопка мыши нажата на элементе поль- зовательского ввода и отпущена па текстовом элементе, то событие onmousedown возникает на элементе пользовательского ввода, событие onmouseup возникает на текстовом элементе, а событие, onclick не возникает вообще. Событие oncl ick возникает на элементе пользовательского ввода только в том случае, если кнопка мыши была нажата и отпущена на одном элементе. Поскольку события onclick и ondbiciick могут возникнуть на элементе, ко- торый является общим для элементов, на которых кнопка мыши была нажа- та и отпущена, то данные два события могут возникнуть на элементах, ко- торые не являются концевыми узлами в дереве документа. Концевые узлы (leaf nodes) представляют собой самые глубокие узлы документа, которые служат для записи содержания. События onclick и ondbiciick являются не- стандартными пользовательскими событиями. С учетом нескольких исклю- чений, которые будут введены в последующих главах, все остальные собы- тия мыши и клавиатуры всегда начинаются на концевых узлах и поднима- ются (всплывают) вверх по иерархии. Ниже перечислен порядок генерации событий onmouse и onclick: 1. onmousedown 2. onmouseup 3. onclick При возникновении двойного нажатия кнопки мыши последовательность событий продолжается следующим образом: 4. onmouseup 5. ondbiciick События onmouseover и onmouseout События onmouseover и onmouseout возникают при подведении пли снятии указателя мыши с элемента на странице. Данные события мыши представ- ляют те же параметры, что и события onmousedown и onmouseup. Они возни-
Глава 3. Модель событий динамического HTML 91 кают только один раз на концевых узлах документа и поднимаются вверх по иерархии элементов вместо возникновения при всех граничных условиях. Рассмотрим следующий код HTML: <HTML> <HEAD> <TITLE> Через границы и за пределами границ </TITLE> </HEAD> <BODY> <Н1> Это заголовок. </Н1> <DIV> <РХВ>Добро пожаловать </В> на мою страницу. </Р> </DIV> </BODY> </HTML> На данной HTML-странице при перемещении мыши по телу документа к полужирному тексту параграфа возникает одно событие onmouseevent на элементе Body, а событие onmouseover возникает на элементе в. Поскольку событие всплывает, то все элементы, границы которых пересекает событие, получают уведомление о событии. Когда указатель мыши переходит от выделенного полужирным начертанием тексту к невыделенному тексту, то на данном элементе возникает событие onmouseout, которое всплывает через параграф. Это важно отметить, по- скольку параграф может получить событие onmouseevent, когда указатель мыши все еще находится над параграфом. Для точной проверки, сместился ли указатель мыши с элемента, используй- те метод элемента contains наряду со свойством toEiement события onmouseout, указывающим на новый элемент, к которому переместился ука- затель мыши. Метод contains указывает, содержится ли один элемент внут- ри другого элемента. С помощью простого кода можно проверить элемент назначения, чтобы выяснить, содержится ли он внутри другого элемента, на котором возникло событие. Если это так, то указатель мыши все еще нахо- дится на сгенерировавшем событие элементе. В данном примере обработчик событий onmouseout будет присоединен к событию onmouseout элемента для проверки того, что указатель мыши все еще находится на элементе: <SCRIPT LANGUAGE= ”JavaScript"> function testexit(sre) ( //Проверка, что указатель мыши действительно находится на элементе. if (!sre.contains(event.toElement)) { //Указатель мыши сместился с элемента. ( > </SCRIPT> <Н1 ONMOUSEOUT-- ''testexit (this) ; ”> Некоторый <ЕМ>текст</ЕМ> </Н1>
92 Часть I. HTML и программирование сценариев В данном примере указатель this, представляющий элемент, на котором возникло событие, должен быть передан в функцию. Свойство srcEiement объекта event не может быть использовано вместо него, поскольку оно мо- жет быть дочерним элементом. Например, при перемещении указателя мы- ши через отмеченный текст в предыдущем заголовке именно отмеченный текст, а не заголовок н1, является элементом srcEiement. Этот метод работает при подведении указателя мыши к элементу, и почти идентичный код выполняется дня события onmouseover. Единственное отли- чие заключается в том, что свойство fromElement следует проверить при по- мощи метода contains: function testenter(src) ( if (!src.contains(event.fromElement)) ( //Указатель мыши подведен к элементу. ) ) Событие onmouseover возникает, когда указатель мыши перемещается через элемент. Ниже приведен порядок генерации событий onmouseover, onmousemove и onmouseout при пересечении границы указателем мыши: 1. onmouseout 2. onmousemove (может возникнуть несколько раз). 3. onmouseover Событие ondragstart В настоящее время динамический HTML обеспечивает ограниченную под- держку операций перетаскивания. Одиночное событие, связанное с перетас- киванием, представлено в объектной модели в качестве альтернативы пове- дения по умолчанию. Когда пользователь нажимает и, удерживая кнопку мыши, перетаскивает элементы документа, такие как изображения и ссыл- ки, эти элементы принимают участие в операции перетаскивания. Возможны случаи, когда такое поведение будет препятствовать выполнению авторских замыслов. Для отмены встроенного поведения представлено со- бытие ondragstart. Данное событие в сущности служит выполнению одной цели — предоставить разработчику возможность отменить событие путем возвращения значения false. Существует тесная связь между отменой события onmousemove и события ondragstart. Для предотвращения операции перетаскивания элемента отме- ните событие ondragstart. При создании собственных моделей операции пе- ретаскивания элемента обычно также следует отменить событие onmousemove.
Глава 3. Модель событий динамического HTML 93 Пример в главе 12 моделирует перетаскивание путем использования события onmousemove для перемещения позиционированных злементов на экране. Данный метод хорошо рабо- тает при обеспечении поддержки перетаскивания внутри страницы. Динамический HTML пока не позволяет программировать перетаскивание между фреймами и окнами. События onselectstart и onselect Динамический HTML представляет два события для полного отслеживания выбора пользователя в документе: onselectstart и onselect, которые запус- каются в порядке перечисления. Подобно событию ondragstart событие onselectstart запускается только если должен быть сделан выбор, обычно когда пользователь щелкает мы- шью по некоторому элементу в документе. Цель данного события заключа- ется в запрещении выделения области документа. Важно учесть, что это предотвращает только инициализацию выделения фрагмента. Например, в приведенном ниже документе, если пользователь не может выделить строку Scott’s Page. <HTML> <HEAD> <TITLE> onselectstart Пример </TlTLE> </HEAD> <BODY> <Hl>Welcome to <EM STYLE= "cursor:hand" ONSELECTSTART- "event.returnValue=false;">Scott's Page </EM> </Hl> </BODY> </HTML> Однако если пользователь щелкает кнопкой мыши по тексту за пределами строки Scott's Page и перетаскивает указатель мыши через строку Scott’s Page, то текст будет выделен, поскольку отменена только инициализация выделения. Свойство CSS cursor используется для изменения указателя мыши на зна- чок "рука". Путем добавления обработчика событий onclick можно опреде- лить индивидуальное действие, которое произойдет, если пользователь щелкнет по строке. Комбинация свойства cursor и обработчика событий onselectstart обеспечивает уровень управления, одинаковый с доступным по умолчанию для ссылок. Событие onselectstart всплывает вверх по структурной иерархии докумен- та. Поэтому возможно перехватить его и вернуть значение false. Это лишает
94 Часть I. HTML и программирование сценариев пользователя возможности выделить текст в документе. Событие onseiectstart следует использовать только в тех ситуациях, когда встроенное выделение текста может привести к возникновению проблем с пользовательским ин- терфейсом на странице. Событие onselect следует за событием onseiectstart и возникает во время выделения текста. Оно возникает много раз по мере того, как пользователь расширяет или сужает выделение. Событие onselect не всплывает. Оно воз- никает в разделе документа, в котором производится выделение фрагмента — в элементе документа Body для текстового содержания или в элементах управления вводом. События клавиатуры Динамический HTML обеспечивает три события для отслеживания нажатий клавиш пользователем: onkeydown, onkeyup и onkeypress, которые возникают в этом порядке. События onkeydown и onkeyup возникают при нажатии и от- пускании клавиши на клавиатуре. Событие onkeypress возникает при нажа- тии любой клавиши <ANSI>. Событие event представляет четыре свойства .тая определения состояния клавиатуры при возникновении данных событий, приведенные в табл. 3.4. Свойства shiftKey, altKey и ctrlKey совпадают со свойствами для событий мыши. Таблица 3.4. Свойства события even t для определения состояния клавиатуры Свойство Значение keyCode ASCII-код нажатой клавиши. Установка данного свойства равным нулю в обработчике события onkeypress отменяет событие. Установка дан- ного свойства равным положительному значению заменяет нажатую клавишу на клавишу с отличным значением ASCII shiftKey Состояние клавиши <Shift> (true/false) altKey Состояние клавиши <Alt> (true/false) ctrlKey Состояние клавиши <Ctrl> (true/false) Событие прокручивания Элемент Body, а также многие другие элементы, могут иметь полосы про- крутки. Когда один из этих элементов или его полоса прокрутки прокручи- вается, возникает событие onscroll. Событие прокручивания возникает, когда пользователь явно прокручивает полосу прокрутки или неявно про- кручивает элемент посредством другого действия. Например, нажатие ссыл-
Глава 3. Модель событий динамического HTML 95 ки в закладке генерирует событие onscroli, если требуется прокрутить документ для просмотра элемента. Событие onscroli не может отменить прокручивание, поскольку запускается после завершения прокручивания. Данное событие возникает только для прокручиваемого элемента (например, для элемента Body) и не всплывает. События фокуса Динамический HTML предоставляет два события, связанных с фокусом: onfocus и onblur. Событие onfocus возникает, когда элемент активизируется после щелчка по нему мышью или с помощью клавиатуры. Элемент, кото- рый потерял фокус, получает событие onblur. Фокус могут получать только элементы пользовательского ввода и тело документа. Поэтому щелчок по содержанию HTML-документа приводит к получению события onfocus те- лом документа, а не элементами содержания. Событие onblur также возникает, когда другое приложение или окно акти- визируется в текущем фрейме или приложении. Поэтому при переключении между окнами текущий элемент получает событие onblur. Событие onfocus возникает для данного элемента при возвращении в окно. Создание расписания перечисленных событий во взаимосвязи с окном имеет ряд сложно- стей, которые будут описаны в главе 5. Событие help Документ представляет событие help, которое возникает, когда пользователь запрашивает файл справки для документа, используя клавишу <FI>. Данное событие не возникает, когда пользователь выбирает пункт Help из меню Help. Событие onheip сначала возникает на элементе с фокусом и затем всплывает вверх по иерархии. Действие по умолчанию для данного события заключается в отображении встроенного файла справки, но данное событие может быть отменено для отображения индивидуального файла справки. Событие onheip также возникает в модальных диалоговых окнах, которые поддерживаю!' контекстно-зависимую справку посредством значка Help в строке заголовка. Путем нажатия значка Help пользователь может изменить вид указателя мыши на специальный курсор справки. Когда пользователь выбирает элемент, используя данный курсор, то на элементе возникает со- бытие onheip, которое затем всплывает к родительским объектам. Обработчик события onheip обычно отображает индивидуальный файл справки. Обработчик может вызвать метод showHeip для отображения файла справки Windows (HLP) пли метод open для отображения файла HTML. Ме- тоды showHeip и open являются методами объекта window. Метод showHeip может также отображать HTML-файлы, но метод open поддерживается
96 Часть I. HTML и программирование сценариев большим количеством браузеров и предлагает больше возможностей для управления отображаемым окном. Метод open описан в главе 5. Примеры событий В данном разделе приведены две программы, иллюстрирующие возможно- сти архитектуры событий, описываемой в данном разделе. С помощью при- мера Event Tutor вы можете проверить страницу и просмотреть события, которые возникают при взаимодействии с ней. Код примера Event Broadcaster предоставляет общий механизм захвата не- сколькими обработчиками каждого события. Event Tutor Для лучшего изучения всплывания событий в число примеров, находящих- ся на прилагаемом компакт-диске для главы 3, включен HTML-документ с названием tutor.htm, который может показать все события, возникающие на странице. На рис. 3.2 показано приложение Event Tutor. Q Event Tutrn • Microsoft Internet Еиркмег вад Events P MouseDown Г* MouscOvcr Г" MouseMove Г MouseOut P MouseUp Г“ KeyDown Г" Keypress Г KeyUp Г* Select Г* SelectStart P Click Г DblClick П Focus Г Blur Г1 Change Г DragStart c.mnouaedoun: P orunGusedoun: BODY o:uoousedoun; HTML onmoueeup: P jHWcuseup, BODY Onmouseup; HTML onclick: P onclick: BODY onclick: HTHL Event Tutor Has page demonstrates how event bubbling works. In the pane! to the left, select the events you want tracked Every time one of the specified events , occurs in this frame, it will be reported tn the text box tn the left frame Remember that events bubble, so a large number of events may be reported H (Try mousemove for an example ) » The source code for this document has no event handlers AU the hard woi k is 4 done by the document in the other frame, so you can easily experiment with £! any sample document Sample Controls Text Box | " Radio Button 1 Radio Button 2 Г: Check Box to 0'=™ Рис. 3.2. Приложение Event Tutor
Гпава 3. Модель событий динамического HTML 97 В данном примере можно выбрать элементы, которые следует отслеживать в документе, находящемся в правом фрейме. Когда возникает выбранное со- бытие на элементе в правом фрейме, об этом сообщается в текстовом окне в левом фрейме. Работа с данным примером хорошо иллюстрирует, как собы- тия всплывают вверх по иерархии. Ниже приведен исходный код из файла events.htm, используемый для создания примера Event Tutor. Данный код демонстрирует отслеживание событий через фреймы — ме- тод, который подробно обсуждается в главе 5. В примере использована модель представления объектов как связанных мас- сивов и создания индивидуальных функций, принятия в JavaScript. <HTML> <HEAD> <TITLE>Event Tutor</TITLE> <STYLE TYPE="text/css”> caption {font-weight:bolder; color:navy) </STYLE> <SCRIPT LANGUAGE="JavaScript"> // Данный пример доступен только на JavaScript (This example is // available in JavaScript only) function outputEvent(src, eventName) ( // присоединение имени события к текстовой области (append event // name to the text area control.) document.all.txtEvents.value += eventName+": "+src.tagName +"\n"; ) function setupEvents() ( // Пользователь установил флажок // Захват или удаление обработчиков событий if ("checkbox"=еvent. srcEiement. type) { var handler - event.srcEiement.checked ? new Function("outputEvent(this,’”+event.srcEiement.id+"')): null; var allSample = parent.frames.sample.document.all; // Добавление индивидуального обработчика событий для всех // элементов в другом фрейме. for (var intLoop=0; intLoop < allSample.length; intLoop++) ( // Обращение к свойству событий, которое соответствует // идентификатору установленного флажка allSample(intLoop](event.srcEiement^id] “ handler) ) ) </SCRIPT>
98 Часть I. HTML и программирование сценариев c/HEAD> CBODY> CFORM NAME="EVENTS"> CTABLE WIDTH=100% ONCLICK="setupEvents () CELLPADDING=4> cCAPTION>EventscBR>Sel.ect Events to Trackc/CAPTION> CTR VALIGN="Top"XTD NOWRAP> <!— Обратите внимание на соглашения об именовании, которые используются ниже. Для добавления событий идентификатор должен указать имя события --> CINPUT TYPE=CHECKBOX ID=onmousedown> CLABEL FOR=onmousedown>MouseDownc/LABEL>cBR> CINPUT TYPE=CHECKBOX ID=onmouseover> CLABEL FOR=onmouseover>MouseOverc/LABELXBR> CINPUT TYPECHECKBOX ID=onmousemove> CLABEL FOR=onmousemove>MouseMovec/LABELXBR> CINPUT TYPECHECKBOX ID=onmouseout> c LABEL FOR=onmouseout >Mous eOut c/LABEL> CBR> CINPUT TYPE=CHECKBOX ID=onmouseup> CLABEL FOR=onmouseup>MouseUpc/LABEL>CBR> CINPUT TYPE=CHECKBOX ID=onkeydown> CLABEL FOR=onkeydown>KeyDownc/LABELXBR> CINPUT TYPE=CHECKBOX ID=onkeypress> CLABEL FOR=onkeypress>KeyPressc/LABELXBR> CINPUT TYPE=CHECKBOX ID=onkeyup> CLABEL FOR=onkeyup>KeyUpc/LABELXBR> C/TDXTD NOWRAP> CINPUT TYPE=CHECKBOX ID=onselect> CLABEL FOR=onselect>Selectc/LABELXBR> CINPUT TYPE=CHECKBOX lD=ondragstart> CLABEL FOR=ondragstart>DragStartc/LABELXBR> CINPUT TYPE=CHECKBOX ID=onselectstart> CLABEL FOR=onselect>SelectStartc/LABELXBR> CINPUT TYPECHECKBOX ID=onclick> CLABEL FOR=onclick>Clickc/LABELXBR> CINPUT TYPECHECKBOX ID=ondblclick> CLABEL FOR=ondblclick>DblClickc/LABEL>CBR> CINPUT TYPECHECKBOX ID=onfocus> CLABEL FOR=onfocus>Focusc/LABELXBR> CINPUT TYPECHECKBOX ID=onblur> CLABEL FOR=onblur>Blurc/LABELXBR> CINPUT TYPECHECKBOX ID=onchange> CLABEL FOR=onchange>Changec/LABEL> c/TDX/TR> c/TABLE> c!— Текстовая область для вывода последовательности событий —> CDIV ALIGN=CENTER>
Глава 3. Модель событий динамического HTML 99 <TEXTAREA ID=“txtEvents" STYLE="width:95%" R0WS=14></TEXTAREA> </FORM> </BODY> </HTML> Вы можете поэкспериментировать с данным кодом в любом документе, скопировав его с компакт-диска на жесткий диск. Замените файл satnple.htm на любой файл по вашему выбору. Вы можете также запустить пример на компакт-диске, открыв файл tutor.htm, который использует файлы sam- ple.htm и events.htm. Event Broadcaster Модель событий динамического HTML в целом ограничена отношениями "один-к-одному” между событием и обработчиком события. Однако воз- можны случаи, когда потребуется связать несколько действий с одним со- бытием. Такая связь может быть реализована путем написания процедуры для события, которая вызывает каждое действие последовательно, или дан- ный процесс целиком может быть автоматизирован путем использования указателей функций JavaScript. Event Broadcaster обобщает связывание событий, используемое динамиче- ским HTML, для поддержки механизма регистрации, который может быть использован для связывания нескольких действий с одним событием. Этот пример содержит небольшой многократно используемый набор функций, которые позволяют связывать действия со всеми событиями. Все данные действия могут также выполняться условно. На основе данного кода вы можете создать повторно используемые обработ- чики событий, которые легко могут быть вставлены в любую Web-страницу без изменения остального кода. Данный метод использует модель регистра- ции .тля обеспечения функциональности регистрации элемента с опреде- ленным действием. Реестр заменяет разработчика, который непосредственно работает с кодом события. Несмотря на то, что данный механизм существенно упрощает написание элементов повторно используемого кода, следует принять меры, чтобы многочисленные действия одного обработчика событий пли документа не вступали в противоречие. Алгоритм такой защиты отсутствует, поэтому но- вые функциональные возможности следует добавлять осторожно. С целью повышения эффективности работы следует исключить взаимодействие меж- ду функциями одного события. Приведенный ниже код представляет целиком весь код реестра Event Broad- caster. Такой код может быть написан только на языках, поддерживающих динамическое создание функций — поэтому данная функциональная воз- можность не может быть реализована в VBScript. Однако данный код не за-
100 Часть I. HTML и программирование сценариев прещает указать действие и зарегистрировать обработчик событий, написан- ный на VBScript. <SCRIPT LANGUAGE™"JavaScript"> 11 Код Event Broadcaster Registry // Данный код связывает многочисленные обработчики событий с одним // событием. function runHandler(eventName, eventSrc) ( // Это общий обработчик событий. // Для всех событий данная функция проверяет условие и // запускает соответствующий код. var src = event.srcEiement; // Сначала проверяется srcEiement. for ( var intLoop = 0; intLoop < eventSrc.manager[eventName].length; intLoop+4) if (eventSrc.manager[eventName][intLoop].condition(src) ) eventSrc.manager(eventName](intLoop).doAction(src); src = src.parentEleinent; // Переход по дереву иерархии и остановка на элементе, который // является источником события. // Для документа tagName равно null; переход по всему дереву. var top = (this.tagName == null) ? "HTML": this.tagName; while (top!=src.tagName) ( for ( var intLoop = 0; intLoop < eventSrc.manager[eventName].length; intLoop+t) if (eventSrc.manager[eventName][intLoop].condition(src) eventSrc.manager[eventName][intLoop].doTree) eventSrc.manager[eventName][intLoop].doAction(src); src ™ src.parentElement; ) } function setupHandler(eventName, eventSrc) < // Создание нового обработчика функций для события. eventSrc[eventName] ™ new Function("runHandler('" + eventName + ”',this);"); } function alwaysTrue() ( // Используйте данную функцию, если не собираетесь проверять // условия, return true; ) function register(eventName, action) { // Это общая процедура регистрации события.
Глава 3. Модель событий динамического HTML 101 // Параметры (в соответствующем порядке): // eventName — Имя события, с которым будет установлена связь // action — Код, который должен быть запущен при // возникновении события И condition, (optional) Условие для запуска действия; // по умолчанию равно true // doTree (optional) Определяет необходимость перехода по / / всем узлам дерева II по умолчанию равно false И eventSrc (optional) Элемент, с которым связано событие; // По умолчанию равно document // Определяет источник события var eventSrc = (null != arguments[4])? document.all[arguments(4]I: document; // Проверяет существование диспетчера событий на объекте. if (null == eventSrc.manager) eventSrc.manageг = new Object; // Проверяет наличие диспетчера событий для определенного // события. if (null==eventSrc.manager[eventName]) ( eventSrc.manager[eventName] = new Object; eventSrc.manager[eventName].length = 0; setupHandler(eventName,eventSrc); ) // Добавляет обработчик событий. var ct = eventSrc.manager[eventName].length*1; eventSrc.manager[eventName][ct] = new Object; eventSrc.manager[eventName][ct].doAction = action; // Проверяет, было ли указано условие. Если условие не указано, // то всегда возвращает true. eventSrc.manager[eventName][ct].condition = null != arguments(2) ? arguments[2]: alwaysTrue; // Проверяет переход по дереву. По умолчанию // равно false. eventSrc.manager[eventName][ct].doTree = null != arguments[3] ? arguments[3]: false; ) function hookupEvents() ( var bindings = document.all.tags("BINBEVENT”); for (var intLoop = 0; intLoop < bindings.length; intLoop**) ( var bind = bindings[intLoop];
102 Часть I. HTML и программирование сценариев if ((null != bind.getAttribute("event")) && (null != bind.getAttribute("action"))) ( var bEvent = bind.getAttribute("event"); . var bAction = new Function("return " + bind.getAttribute("action") + ”(arguments[0))); var bCondition = (null == bind.getAttribute("condition")) ? null: new Function("return " + bind. getAttribute("condition”) + "(arguments[0))); var bTree = ("walk” — bind.getAttribute("tree")); var bSrc = bind.getAttribute("for”); register(bEvent, bAction, bCondition, bTree, bSrc) ; ) ) ) window.onload = hookupEvents; </SCRIPT> В данном коде использованы элементы динамического HTML и JavaScript. Все методы, которые были использованы в данном примере, обсуждаются в следующих главах. Например, HTML не определяет или не поддерживает тег <bindevent>. Напротив, динамический HTML представляет нераспозна- ваемые элементы в объектной модели. Вы можете использовать данный элемент для связи информации и расширения сценариев без изменения кода. Для использования данного кода напишите вызывающую его функцию и опишите ее связь с событием определенного объекта на странице. Приведенный ниже код демонстрирует, как динамические эффекты могут быть добав- лены и зарегистрированы в приведенном выше сервисе связывания. Динамическое измене- ние стиля элемента обсуждается в главе 1I. <SCRIPT LANGUAGE="JavaScript"> // эффект динамического стиля mouseover function swapEffects(sre) ( 11 Поменять эффект с элементом className if (null!=src.getAttribute("effect")) ( var tempClass = sre.className sre.className = sre.getAttribute("effect”) sre.setAttribute("effect",tempClass)' ) )
Глава 3. Модель событий динамического HTML 103 function checkEffect(src) ( // условие, которое следует проверить перед заменой эффекта return (src.getAttribute("effect”)!=null); ) </SCRIPT> Данный сценарий определяет действие и условие для обмена эффектов с атрибутом класса. Приведенный ниже код HTML связывает данный код с событиями onmouseover И onmouseout документа: <BINDEVENT event="onmouseover" action=”swapEffects" condition“”checkEffeet" tree="walk"> <BINDEVENT event="onmouseout" action="swapEffects" condi ti on="checkEffec C" t ree="wa1k"> Индивидуальное связывание событий является мощным механизмом в том смысле, что автору не требуется знать как происходит захват кода, он может просто вставить код в свою страницу. С помощью легко используемого HTML данный код может быть связан с любым событием любого объекта. Действительная мощь этой модели раскрывается, когда пользователь пыта- ется связать другое действие с событиями onmouseover или onmouseout. Обычно это требует написания индивидуальных обработчиков событий оп- mousemove или onmouseout для вызова последовательности различных дейст- вий. Для использования продемонстрированного метода необходимо только вставить новую выполняемую функцию в документ и связать ее с событием, используя другой тег <btndevent>. Код реестра автоматически управляет правильными наборами обработчиков событий и гарантирует, что они за- пускаются для каждого события. Тег <bindevent> поддерживает дополнительный атрибут for для связи собы- тия непосредственно с определенным элементом. По умолчанию событие присоединяется к документу. Атрибут for использует идентификатор (ID) элемента, с которым связывается событие.
.Глава 4 U Окно браузера В данной главе вы узнаете о том, как программировать окно браузера, объ- екта высшего уровня в объектной модели динамического HTML. Доступ к информации о браузере и содержащемся в нем документе может быть осу- ществлен посредством объекта window. В окне могут быть отображены два типа HTML-документов: документ с набором фреймов и стандартный HTML-документ. Документы с набором фреймов разделяют одиночное окно на многочисленные фреймы, доступ к которым осуществляется независимо. В главах 5 и 6 эти два типа документов обсуждаются подробно. Объект window представляет информацию документа (включая информацию о фреймах на странице и URL для текущего документа) и предоставляет доступ к информации о самом браузере (включая торговую марку компью- тера клиента, версию объекта navigator и поддерживаемые им элементы), доступ к информации событий и, что наиболее важно, доступ к объекту document, который представляет сам HTML-документ. Объект window также позволяет перемещаться в файле истории, настраивать браузер и переме- щать окно. В данной главе и главе 5 приведено объяснение методов манипулирования браузером и содержащимся в нем документом, используя объект window. В этой главе внимание сфокусировано на членах процедуры манипулирова- ния текущим окном. В главе 5 будет продолжено обсуждение данной темы и продемонстрированы методы манипулирования наборами фреймов и много- численными экземплярами браузера. В данной главе рассмотрены следующие темы: □ Объект window. Представлено краткое введение в объект window и его связи с другими объектами, включая уникальные взаимоотношения с глобаль- ными переменными, которые ведут себя как общие члены объекта window.
Гпава 4. Окно браузера 105 □ Среда window. В данном разделе показано, как манипулировать средой браузера — включая строку состояния браузера, местоположение доку- мента, список истории и разрешение экрана монитора пользователя. □ События окна. Объект window представляет изменения в состоянии доку- мента посредством нескольких событий, которые помогут определить момент окончания загрузки документа и то, является ли документ все еще активным. □ События таймера. Объект window также представляет методы создания таймеров. Таймеры представляют собой события, которые выполняют определенную программу по истечении заданного промежутка времени. □ Свойство clientinformation или navigator. Объект navigator содержит определенную информацию о клиенте. Данная информация, которая включает в себя название браузера, его версию, установленные пользова- телем параметры, позволяет сценариям определять возможности клиента и настраивать страницу в соответствии с ними. Объект window Как упоминалось выше, объект window представ- ляет собой объект высшего уровня в динамиче- ском HTML. В упрошенном виде объект window можно представить в виде контейнера для доку- мента или других окоп. Окно, содержащее другие окна, представляет собой основу набора фреймов (frameset). На рис. 4.I показана иерархия объектов wj ndow. Объект window содержит информацию о браузере и существует до тех пор, пока существует окно приложения браузера. Это означает, что когда пользователь просматривает различные страницы документа, объект window остается доступным, даже если текущий документ изменяется. Рис. 4.1. Иерархия объектов window Ссылка на объект window Поскольку объект window представляет собой объект высшего уровня в объ- ектной модели HTML, не требуется явно ссылаться на него при обращении к свойству окна. Приведенные ниже строки кода выполняют одинаковые действия:
106 Часть I. HTML и программирование сценариев window.location.URL // Явная ссылка на объект window. location.URL // Неявная ссылка на объект window. Кроме того, объект window представляет свойство self, которое действитель- но возвращает окно. Поэтому приведенные ниже пять строк кода ссылаются на одно свойство name: name self.name window.self.name window.self.window.name window.window.name Неявные ссылки на окно работают только для программ, которые ссылают- ся на текущее окно. Для создания ссылки на другие окна или фреймы, ко- торые не являются текущими, должны быть указаны явные ссылки на опре- деленные объекты window. Свойства document и event Свойство document возвращает объект document, представляющий страницу, которая содержится в окне. Доступ к стилю, структуре и содержанию доку- мента может быть осуществлен посредством свойства document. Как упоминалось в главе 3, свойство event объекта window возвращает объ- ект event, который предоставляет информацию о текущем событии. Объект event доступен только в ходе возникновения последовательности событий и возвращает null во всех остальных случаях. В главе 5 объясняется, как уста- новить реакцию на события, которые возникают в других окнах или доку- ментах. Глобальные переменные и определяемые пользователем свойства Как упоминалось в главе 2, при написании сценариев в динамическом HTML отсутствуют доступные глобальные переменные. Все переменные, которые описываются за пределами функции или обработчика событий, автоматиче- ски добавляются как определяемые пользователем свойства объекта window. Когда пользователь покидает страницу, то ее переменные удаляются из ок- на. Это осуществляется по соображениям безопасности — чтобы новая страница не пыталась читать состояние предыдущей страницы. Поэтому время жизни определяемых пользователем свойств объекта window равно времени жизни сценария, даже если объект window существует до тех пор, пока окно приложения не будет удалено. При загрузке новой страницы
Глава 4. Окно браузера 107 объект window проявляет только встроенные свойства, определяемые дина- мическим HTML. Установка имени окна Все окна создаются без имени. Вы можете дать окну имя путем присвоения строки свойству name, или указать имя для фрейма, создаваемого как часть набора фреймов. Свойство name определяет пункт назначения для ссылки или результатов форм. По умолчанию все страницы направлены на текущий фрейм или фрейм или окно, определенные тегом <base target= windowName>. Можно изменить данную цель путем назначения атрибута target для ссылки или элемента Form с указанием именованного окна, в котором должен появлять- ся документ. Свойство name объекта window сохраняется пользователем при перемещении пользователя на страницу, чтобы гарантировать, что поддерживается цель фрейма. Передача строк программного кода Объект window представляет метод eval, который может интерпретировать передаваемую строку как программу и возвращать результат. Данная про- грамма выполняется в контексте запущенного в данный момент языка на- писания сценариев. Среда окна В данном разделе обсуждается манипулирование окном браузера и окру- жающей средой. Окно браузера состоит из ряда областей, которыми можно управлять с помощью сценариев, включая местоположение текущего ото- бражаемого документа, текст строки состояния, историю и разрешение эк- рана монитора. На рис. 4.2 показаны различные элементы окна. Строка состояния Текст строки состояния обычно отображается в нижней части окна браузе- ра. Доступ к сообщениям строки состояния возможен посредством свойств defaultstatus и status. Оба свойства представляют строки, допускающие операции чтение/запись. Разница между ними заключается в том, что свой- ство status используется для сообщения, которое отображается временно, а свойство defaultstatus отображает сообщение "до тех пор, пока свойство defaultstatus не изменится или пользователь не покинет окно браузера, как показано в приведенном ниже коде:
108 Часть I. HTML и программирование сценариев <HTML> <HEAD> <TITLE> Текст состояния </TITLE> CSCRIPT LANGUAGE-"JavaScript"> function setstatus() { // Отображаемое сообщение статуса window.defaultstatus = "Default status"; // Temporary message to display window.status = "Temporary status"; ) C/SCRIPT> </HEAD> <BODY> <FORM> CINPUT TYPE-BUTTON VALUE="Change Status" ONCLICK="setStatus();"> c/FORM> </BODY> C/HTML> Кнопки Back (Назад) и Forward (Вперед) Адрес текущего документа Wirn'nw [ nvHonnent * MlCtOtoll Inb'iru'l I ич-i _______________. ___________ HRE3 r<4 thdWeb ’ ^P«x5uciNer«^jTcdaf/t LriJ ^WebGeley Window environment NJ) Per® Рис. 4.2. Элементы окна, управляемые с помощью объекта window
Гпава 4, Окно браузера 109 При нажатии кнопки Change Status (Изменить состояние) строка статуса отображает строку Temporary status (Временное состояние). После переме- щения мыши сообщение изменяется на Default status (Состояние по умол- чанию). Когда пользователь покидает страницу, в строке состояния выво- дится сообщение по умолчанию. Используя события onmouseover и onmouseout для элемента, очень просто установить отображение специального сообщения состояния, когда указа- тель мыши находится на элементе: <А ONMOUSEOVER» "window.status="Go Home'”' ONMOUSEOUT» "window.status»"" HREF» "home.htm"> Top page </A> Пример программы для создания текста бегущей строки состояния, в кото- ром используется свойство status и таймеры, представлен в разделе "Текст бегущей строки состояния" ниже в данной главе. Кнопки Back и Forward Динамический HTML предоставляет методы для создания индивидуальных кнопок истории. Хотя доступ к действительным URL, просмотренным поль- зователем, невозможен, объект history представляет три метода, которые моделируют нажатие кнопок истории на панели инструментов: методы до, forward и back. Свойство length представляет число элементов в списке ис- тории. Приведенный ниже код создает простые кнопки Back (Назад) и For- ward (Вперед): <нтмь> <HEAD> <TITLE> Кнопки истории </TITLE> </HEAD> <BODY> <FORM NAME»"Browse”> CINPUT TYPE=BUTTON VALUE="Back" ONCLICK="history.back();"> CINPUT TYPE=BUTTON VALUE="Forward" ONCLICK="history.forward();"> </FORM> </BODY> </HTML> Местоположение окна Адрес страницы в окне определяется с помощью свойства location, которое ссылается на объект, идентифицирующий адрес URL. Преобразование URL
110 Часть I. HTML и программирование сценариев в простые для использования свойства упрощают извлечение и манипулиро- вание URL. Свойства объекта location Большинство свойств объекта location разделяют URL на простые в ис- пользовании компоненты. Свойства, которые связаны с URL, перечислены ниже: protocol: // hostname -.port/pathname? search#hash Почти все URL имеют свойства protocol (протокол), hostname (имя хоста) и pathname (путь). Свойства port (номер порта), search (поиск) и hash (данные) могут не иметь связанных значений. Свойство search представляет строку поиска, которая обычно указывается для сценариев CGI (Coimnon Gateway Interface — общий шлюзовой интерфейс) серверной части. Свойст- во hash представляет закладку на странице. Кроме того, объект location использует несколько дополнительных свойств, которые объединяют упомянутые выше свойства. Например, свойство host просто возвращает значение hostname, после которого указано двоеточие и номер порта (port). Свойство href является полной ссылкой URL, которая представлена как отдельная строка. Присвоение значения любому изданных свойств приводит к тому, что брау- зер начинает немедленно искать новую страницу. Для большинства опера- ций свойство href является одним из тех свойств, значение которого необ- ходимо установить для загрузки новой страницы. Можно также использо- вать метод replace, который будет рассматриваться ниже. Методы объекта location Для объекта location используются два метода: reload ((force!) и replace (uri). Вызов метода reload аналогичен нажатию кнопки Refresh (Обновить) браузера — оба действия вызывают загрузку целиком всей страницы, если она была изменена. Если указать в качестве параметра force значение tree, то может произойти перезагрузка страницы, даже если сервер сообщает, что страница не была изменена. Метод replace осуществляет переход на новую страницу. Метод работает аналогично присвоению значения свойству href., за исключением того, что метод replace не добавляет текущую страницу в список истории. Метод replace полезен для переадресации URL на клиентской стороне, как пока- зано в приведенном ниже примере: <HTML> <HEAD> <TITLE> Определение названия браузера </TITLE> <SCRIPT LANGUAGE-"JavaScript">
Гпава 4. Окно браузера 111 // Загрузить другую версию страницы для пользователей Netscape. if ("Netscape" -= navigator.appName) location.replace("nsversion.htm"); </SCRIPT> </HEAD> <BODY> <!- Страница для других браузеров -> </BODY> </HTML> Информация экрана Объект screen представляет информацию об экране текущего пользователя, включая разрешение экрана и количество цветов, что позволяет вашей про- грамме анализировать возможности отображения экрана пользователя и на- страивать соответствующим образом отображаемое содержание. В табл. 4.1 перечислены свойства объекта screen. Таблица 4.1. Свойства объекта screen Свойство Описание width Горизонтальное разрешение экрана в пикселах height Вертикальное разрешение экрана в пикселах colorDepth Число битов на пиксел, которое используется экраном или буфером availHeight Высота экрана внутри окон браузера availwidth Ширина экрана внутри окон браузера Свойства availHeight и availWidth дают информацию о размерах пользова- тельского экрана, который доступен для окон браузера — то есть, свободное пространство внутри окна браузера, не занятое панелями инструментов. Данная информация может быть также использована во время загрузки для определения режима представления документа: могут быть применены раз- личные таблицы стилей или может быть загружен совершенно другой доку- мент. Приведенный ниже код демонстрирует переадресацию пользователей, у которых монитор обеспечивает низкое разрешение, на другой документ и отключение таблицы стилей, предназначенной только для пользователей, у которых установлено определенное число цветов экрана: <HTML> <HEAD> <TITLE> Страницы для различных экранов </TITLE> <LINK REL="styleSheet" TYPE="text/css" HREF="256color.css">
112 Часть I. HTML и программирование сценариев <SCRIPT LANGUAGE="JavaScript"> if ((640 >= screen.width) || (480 >= screen.height)) window.location.replace(”lowres.htm”); document.stylesheets[0].disabled = (screen.colorDepth < 8); </SCRIPT> </HEAD> <BODY> <!— Содержание документа —> </BODY> </HTML> События окна Объект window представляет события, которые позволяют управлять текущим состоянием окна. Данные события позволяют определить, загружен ли до- кумент, проверить получение или потерю фокуса, а также позволяют орга- низовать обработку ошибок. События состояния документа События используются для отслеживания загрузки и выгрузки документа. Обработчики данных событий должны всегда записываться в заголовке до- кумента, чтобы они были гарантированно использованы в самом начале процесса загрузки документа. Если события записываются в середине доку- мента, то программа может быть никогда не запущена, если, например, пользователь покинет документ до того, как программа выгрузки будет про- анализирована интерпретатором. События загрузки С загрузкой документа связаны события onload И onreadystatechange. Оба помогают определить момент, когда весь документ будет проанализирован и все элементы загружены. Событие onreadystatechange представляет собой новое событие, которое возникает в документе, а не в окне. Событие onreadystatechange подробно обсуждается в главе 6. Событие onload запускается, когда весь документ проанализирован, но не обязательно сообщает о том, что все объекты документа полностью загруже- ны. Данное событие также поддерживается объектными моделями Netscape Navigator 3.0 и Microsoft Internet Explorer 3.0. События выгрузки С процессом выгрузки связаны события Документа onbeforeunload и onunload. Событие onbeforeunload генерируется сразу же после события onunload. Событие onbeforeunload дает Web-мастеру возможность проверить.
Гпава 4. Окно браузера t ТЗ что пользователь действительно хочет покинуть документ. Данное подтвер- ждение полезно, когда выход из документа может привести к потере ин- формации, поскольку пользователь нс смог получить данные с сервера. На- пример, в процедуре связывания данных, когда пользователь запускает много изменений на компьютере клиента, выход из документа без получе- ния данных, приведет к непреднамеренной потере информации изменений. Связывание данных подробно рассматривается в главе 15. Событие onbeforeunioad может отобразить стандартное диалоговое окно, которое содержит указанный разработчиком текст и спрашивает пользовате- ля, хочет ли он покинуть документ. Для отображения данного запроса уста- новите значение returnvalue равным строке, как показано в приведенном ниже коде. Если не установить значение свойства returnvalue равным стро- ке, то окно может просто выгрузить документ, не отображая диалоговое окно. <SCRIPT LANGUAGE” "JavaScript” EVENT” "onbeforeunioad() "FOR” "window"> event.returnValue= "Введенные вами данные будут потеряны, если вы покинете страницу"; </SCRIPT> На рис. 4.3 показано данное индивидуальное сообщение, отображаемое Internet Explorer 4.0 в ответ на событие onbeforeunioad. Microsoft Internet Explorer Ate you you wjrit to tj'A'tij; (j n (hn pmqc? Your Input HI be losi if you lew? Prers P' stay pa;? Рис. 4.3. Запрос подтверждения выхода с текущей страницы По соображениям безопасности нельзя допускать предотвратить выгрузку документа из окна без вмешательства пользователя. Данное ограничение запрещает документу блокировать систему и требует, чтобы пользователь закрыл приложение браузера или перезагрузил компьютер. Непосредственно перед выгрузкой документа возникает событие onunload. В этот момент невозможно остановить процесс или попросить пользователя не покидать документ. Более того, в данном месте следует записать код за- вершения, поскольку это является последней возможностью для сценария обратиться к документу и его содержимому. События фокуса Термин фокус (focus) применим к окну или элементу, которые находятся в активном состоянии и получают извещения пользователя, такие как собы- тия клавиатуры и мыши. Для того чтобы разрешить определение моментов
114 Часть I. HTML и программирование сценариев получения и потери фокуса окном, окно представляет события onblur и onfocus. В целом, событие onblur генерируется, когда фокус переходит от окна к другому элементу внутри данного или другого окна, и событие onfocus возникает, когда окно получает фокус. Документ, который загружается браузером, первоначально имеет фокус, но не запускает событие onfocus. Когда окно активизировано, каждое действие пользователя в окне будет приводить к возникновению последовательности событий onblur и onfocus. Например, щелчок по документу в окне приводит к возникновению события onblur в окне, за которым следует событие onfocus, даже если окно уже было активизировано. Если исходным документом является набор фреймов, то первоначально на- бор фреймов находится в активном состоянии. Так же как и при загрузке традиционных HTML-документов, загрузка фрейма не запускает событие onfocus. Однако если пользователь переходит к экземпляру фрейма или на- бора фреймов или производит щелчок мышью внутри экземпляра фрейма, то событие onblur запускает набор фреймов и в соответствующем фрейме возникает событие onfocus. Отсюда вытекает первое правило событий фокуса: I Правило I В любом экземпляре браузера одновременно может быть активизирован толь- ко один элемент. Этим элементом может быть объект window, набор фреймов или элемент внутри документа, такой как элементы ввода данных или внедренный объ- ект. При переходе фокуса событие onblur возникает в окне или элементе, и событие onfocus возникает в другом элементе. Документ может содержать любое число доступных для активизации (получения фокуса) элементов, включая элементы ввода, которые находятся в форме, внедренные элементы управления и апплеты. Когда один из этих элементов получает фокус, то событие onblur возникает в предыдущем окне или элементе и событие onfocus возникает на активизируемом элементе. Поэтому можно сформулировать второе правило событий фокуса: / Правило I Каждое изменение фокуса возникает симметрично, то есть событие onblur возникает на элементе, потерявшем фокус, и событие onfocus возникает на элементе, получившем фокус. Методы focus и blur Вы можете передать или снять фокус с окна или'элемента путем вызова ме- тодов focus или blur. Вызов одного из этих методов приводит к выполне- нию соответствующего обработчика событий, только если требуется измене-
Гпава 4. Окно браузера 115 ние состояния. Например, активизированное окно не будет генерировать событие onfocus, если вызывается его метод focus. Однако если окно не ак- тивизировано и затем получает фокус посредством метода focus, то будет запущено событие onfocus. Важно понимать данное различие, поскольку вы не можете положиться на программу, которая выполняется в ответ на все вызовы методов focus и blur. Обработка ошибок Объект window представляет событие опеггог, которое запускается при воз- никновении ошибки в сценарии на странице. Когда ошибка возникает в сценарии, то на экран обычно выводится малопонятное сообщение и за- грузка страницы прекращается. Используя обработчик событий опеггог, страница может отменить вывод встроенного диалогового окна и отобразить более содержательное сообщение. Событие опеггог также дает возможность отменить вывод встроенного диа- логового окна и прекратить загрузку без вывода уведомления, как показано в приведенном ниже коде. Несмотря на простоту данного кода, использо- вать его не рекомендуется. Последствия возникновения ошибки сценария на странице могут быть непредсказуемы, вследствие чего документ перестанет функционировать. <SCRIPT LANGUAGE^ "JavaScript"> function stopAHErrors () { // Ошибки в сценариях не будут приводить к выводу сообщения. return true; // Значение true запрещает появление диалогового окна. ) window.onerror=stopAHErrors; // Захват обработчика ошибок опеггог. thisBadCode.WillNot.GenerateAnError(); // Синтаксическая ошибка. </SCRIPT> В отличие от большинства событий в объектной модели динамического HTML, возврат значения true в событие опеггог отменяет вывод диалого- вого окна. Для всех остальных событий возврат значения false предотвра- щает выполнение событием его действия по умолчанию. Это различие необ- ходимо для поддержания совместимости с событием опеггог в Netscape Navigator 3.0. Вы можете использовать событие опеггог для постепенной обработки оши- бок ввода данных пользователем. В приведенном ниже примере пользова- тель указывает цвет, который применяется к текстовому окну документа. Если пользователь вводит недействительное нЛвание цвета, то в диалоговом окне выводится предупреждение о том, что название цвета является недей- ствительным.
116 Часть I. HTML и программирование сценариев <SCRIPT LANGUAGE="JavaScript"> function doError() { if (arguments[0] == "runtime error 380") ( alert("Invalid Color Name"); return true; ) window.onerror = doError; </SCRIPT> Color: <INPUT TYPE=TEXT ONCHANGE="this.style.color = this.value;” VALUE="Black"> Событие onerror передает обработчику событий три аргумента: описание ошибки, имя файла, в котором возникла ошибка, и номер строки, в которой возникла ошибка. Обработчики ошибок не должны использовать номер строки, поскольку при редактировании текста программы, номера строк бу- дут изменены и обработчики ошибок перестанут работать. Пользовательские события Пользовательские события возникают, когда пользователь взаимодействуете окном — например, когда пользователь изменяет размер окна или прокру- чивает окно. Эти события возникают после выполнения действий, так что обработчики событий не могут их отменить. В главе 5 представлены методы, которые могут быть использованы сценариями для изменения размера или прокручивания окна. Используя каскадные таблицы стилей (Cascading Style Sheets, CSS), можно создавать контейнеры внутри документа, которые поддерживают прокручи- вание и изменение размера. Данные действия запускают для контейнеров те же события, что и для окон. Событие onresize При каждом изменении пользователем размера окна возникает событие onresize. Данное событие позволяет написать код, который изменяет распо- ложение содержания документа или даже других окон относительно теку- щего размера документа. Событие onscroll Событие onscroll запускается каждый раз при Прокручивании документа вручную пользователем или в результате действия, которое приводит к про- кручиванию документа. Например, переход к закладке или использование
Гпава 4. Окно браузера 117 клавиш со стрелками. Свойства для определения текущего положения мар- кера полосы прокрутки представлены при помощи объекта body в самом документе. Взаимодействие с данными свойствами продемонстрировано в главе 5. Их подробное обсуждение можно найти в главе 9. Определение событий окна Все события окна, включая onblur, onfocus, onload, onunlcad и onbeforeunioad, — могут быть определены как атрибуты тега <bohy> на HTML-странице. Это позволяет связать данные события с обработчиком с помощью атрибутов вместо сценариев, как показано в приведенном ниже коде: <нтмь> <HEAD> <TITLE> Захват обработчиков событий </TITLE> <SCRIPT LANGUAGE= "JavaScript"> function doLoad() { // Укажите здесь операции, которые должны быть выполнены при загрузке страницы. ) function doUnloadO ( // Определите операции, которые должны быть выполнены при выгрузке документа window.onload = doLoad; // Захват обработчика событий в сценарии. </SCRIPT> </HEAD> <! — Захват обработчика событий с помощью атрибута элемента Body. -- > <BODY ONUNLOAD= "doUnload();”> </BODY> </HTML> События таймера Таймеры запускают события по истечении определенного интервала времени, а не в результате действий пользователя. Они полезны для анимированных объектов в браузере или для запуска программы по истечении определен- ного интервала времени. Объект window может создавать два типа таймеров: П Таймеры, которые выполняют программу один раз по истечении опреде- ленного промежутка времени. □ Таймеры, которые выполняются циклически и запускают программу с определенными промежутками времени.
118 Часть I. HTML и программирование сценариев Таймеры могут быть добавлены в окно только посредством программы. Они не могут быть определены как атрибуты элемента. Метод setTimeout создает таймер, который выполняется только один раз, а метод .setinterval создает таймер, который выполняется с определенным интервалом времени. Оба метода используют одинаковый набор параметров: var timerRef“window.setTimeout(script, time) var timerRef“window,setinterval(script, time) Можно использовать одноразовый таймер для повторного выполнения об- работчика, если сбросить таймер в обработчике, как показано ниже: <SCRIPT LANGUAGE= ”JavaScript"> var timeEverylOO; function EverylOOO { // Здесь должен быть выполняемый код. /I ... // Сброс таймера. timeEverylOO= setTimeout("EverylOO();", 100); ) //Первый вызов таймера. timeEverylOO=setTimeout("EverylOO();", 100); // Когда пользователь покидает страницу, таймер следует удалить. window.onunload=new Function("clearTimeout(timeEverylOO);"); </SCRIPT> Если вы используете метод setinterval вместо setTimeout, то вам не требу- ется сбрасывать таймер в обработчике. ( Примечание ) Метод setlnterva). был введен в Netscape Navigator 4.0 и Internet Explorer 4 0 для обеспечения совместимости. Если вы пишете программу для браузеров низкого уровня, то используйте метод setTimeout вместо метода setinterval. Можно передать параметры обработчику вручную путем создания строки вызова функции. Приведенный ниже код создает вызов функции с гремя параметрами: var tm = setTimeout ("doThis (" + argl + 23, " + arg3 + ”);", 100); Таймеры создаются C ПОМОЩЬЮ методов setTimeout ИЛИ setlnterva! И могут быть удалены в любой момент, посредством метода удаления clearTimeout или clearinterval. Оба метода удаления принимают в качестве параметра значение timerRef, возвращаемое методом set. Поэтому при установке тай- мера возвращаемое значение следует сохранить в переменной.
Гпава 4. Окно браузера 119 В предыдущем примере таймер удалялся в событии onunload, когда пользо- ватель покидал страницу. Событие onunload запускается непосредственно перед удалением страницы из памяти. Данный шаг является необязатель- ным, но желательным, поскольку это гарантирует, что браузер выгрузит таймер из памяти. Использование таймеров В данном разделе представлены три примера, иллюстрирующие использова- ние таймеров. Первый пример демонстрирует таймер, который переходит на новую страницу по истечении определенного промежутка времени. Таймер использует метод setTimeout, поскольку программа должна быть выполнена конечное число раз. В следующих двух примерах используется метод setinterval. Во втором примере с помощью динамического HTML создает- ся улучшенная полоса прокрутки. В третьем примере создаются электрон- ные часы. Таймеры используются во многих примерах данной книги для создания интересных эффектов. Автоматический переход на страницу Программа в приведенном ниже примере демонстрирует простой таймер, который осуществляет переход на новую страницу по истечении определен- ного промежутка времени. Данный пример также представляет один из эле- ментов динамического содержания путем отображения обновляемого счет- чика. <HTML>• <HEAD> <TITLE> Счетчик </TITLE> <SCRIPT LANGUAGE="JavaScript"» var intLeft =5; // Количество секунд до перехода function leavePage() { if (0 == intLeft) // Ожидание закончилось — осуществляется // переход. document.location = "home.htm"; else { // Счет в сторону уменьшения и вывод изменяющегося // значения счетчика. intLeft -- 1; document.all.countdown.innerText = intLeft + " 11 Осталась одна секунда. setTimeout("leavePage() , 1000); } }
120 Часть I. HTML и программирование сценариев </SCRIPT> </HEAD> <BODY ONLOAD=”setTimeout(1leavePage()', 1000)> <H1> Автоматический переход на страницу </Н1> Переход на <ЕМ> страницу </ЕМ> произойдет через <SPAN ID="countdown"> <!— Вывод исходного значения времени. —> <SCRIPT LANGUAGE»"JavaScript”> document.write(intLeft); </SCRIPT> </SPAN> секунд. </BODY> </HTML> Длительность паузы таймера в секундах определяется значением перемен- ной intLeft. Изменение исходного значения переменной intLeft также ав- томатически обновляет исходное значение, вследствие выполнения простого сценария в теле документа. Текст строки состояния В приведенном ниже примере создается текст строки состояния, которая прокручивается справа налево. Этот пример может быть запущен только в Internet Explorer 4.0, поскольку элемент Body настроен с определяемым пользователем атрибутом для хранения сообщения. Данный метой добавления атрибутов в элементы для определения нового поведения опи- сывается в главе 8. <HTML> <HEAD> <TITLE>Scrolling Status Bar Text</TITLE> <SCRIPT LANGUAGE»"JavaScript"> function spacer(pos) ( // Simple routine to generate spaces var space *- for (var i = 0; i < pos; i++) space += ” "; return space; ) function scrollstatus() ( // Проверка сообщения для бегущей строки. if (null != message) ( with (message) (
Гпава 4. Окно браузера 121 // Перезапуск сообщения. if (position < -text.length) position = maxSpace; // Scroll words off left edge. if (position < 0) ( position—; window.status = text.substring(-position); } else ( // Вывод предварительных пробелов. window.status = spacer(position--) + text; } ) } } function initMessage() ( // Конструктор для объекта сообщения // Отображаемое сообщение является обязательным аргументом, this.text = document.body.getAttribute("message”); // Значение скорости необязательно. if (null != arguments[0]} this.speed = arguments[0]; else this.speed = 10; // Исходное значение предшествующих пробелов this.maxSpace = 130; this.position - maxSpace; // Запуск таймера. this.timer = setinterval("scrollstatus(}", this.speed); return this; ) </SCRIPT> </HEAD> <BODY ONLOAD="message = initMessage(10);" message=”Demo String to Scroll"> Demo Message Page </BODY> </HTML> Электронные часы До появления динамического HTML электронные часы могли быть добав- лены в HTML-документы только с помощью апплетов, изображений со сложными программами или других подобных трюков. Данный пример де- монстрирует, как создавать электронные часы непосредственно в HTML-
122 Часть I. HTML и программирование сценариев документе. В приведенном ниже коде часы помещены внутри элемента Span с идентификатором clock. Каждую секунду (при каждом изменении значе- ния времени) содержание элемента span заменяется на новое значение. <HTML> <HEAD> <TITLE>Ticking Clock</TITLE> <STYLE TYPE="text/css"> Hclock {color:blue; font-size:120%} /* Format the clock. ★/ </STYLE> <SCRIPT LANGUAGE»"JavaScript"» // Проверка того, что используется браузер IE4 или более поздней // версии. var MS = navigator.appVersion.indexOf("MSIE”); window.isIE4 = (MS > 0} S4 (parselnt(navigator.appVersion.substring(MS +5, MS + 6)) >= 4); function leadO(val) ( // Добавление предшествующих нулей при необходимости. return (val < 10) ? ”0" + val.toString(): val; } function buildTimeO { var time = new Dated; var ampm = "AM”; var h = time.getHours(); // Установки времени и определение времени суток (до // полудня/после полудня am/pm). if (h > 12} ( h = h - 12; ampm = ” PM"; } return leadO(h) + ”:" + leadO(time.getMinutes()) + ":" + leadO(time.getSeconds()) + ampm; } function tick() { // Замена значения на часах на текущее время, document, all. clock. innerText = buildTimeO; } </SCRIPT> </HEAD> <!— Запускать таймер, только если используется браузер IE4. —> <!— При выгрузке удалить таймер. —> <BODY ONUNLOAD="if (null != window.tmr) clearinterval (winfiow. tmr) ; " ONLOAD="if (window.isIE4)
Гпава 4. Окно браузера 123 window.tmr = setinterval('tick()1, 999);"> <Hl>Ticking Clock</Hl> <P> Ниже приведены действующие электронные часы, запрограммированные с помощью HTML. </Н1> <P>The current time is: <SPAN ID="clock”> <SCRTPT LANGUAGE=”JavaScript"> // Поддержка сценариев низкого уровня — // вывод исходного значения времени. document.write(buildTime()); </SCRIPT> </SPAN>. </BODY> . </HTML> Данный код также запускается на браузерах низкого уровня, которые под- держивают сценарии. Хитрость заключается в метоле document.write, кото- рый содержится в теле документа для вывода текущего времени в соответст- вующем месте документа. В браузерах, которые поддерживают динамиче- ский HTML, часы будут идти. В браузерах, которые нс поддерживают динамический HTML, отображается только одно значение времени, которое было на часах в момент загрузки страницы. Точность таймера Нельзя полагаться, что события таймера будут происходить с установленной точностью — регулярность генерации события таймера, которое в соответст- вии с разработкой должно возникать каждую секунду, может нарушаться. В зависимости от операционной системы таймер может быть запущен толь- ко после того, как другое приложение или процесс освободит ресурсы для браузера. Нерегулярность работы таймера может возникнуть в случае, если таймер используется для анимации. Анимация может остановиться мгновенно, вме- сто ровного выполнения. Данное отклонение может быть вызвано задерж- кой выполнения таймера, что обусловлено каким-либо другим процессом или самим браузером. Свойства clientinformation и navigator Свойства clientinformation и navigator ссылаются на объект, содержащий информацию о клиенте. Свойство clientinformation было добавлено в Internet Explorer 4.0 как псевдоним для navigator с целью разделения всех предполагаемых взаимоотношений между объектной моделью и определен-
124 Часть I. HTML и программирование сценариев ным браузером. Однако поскольку свойство clientinformation ПОДДерЖИВа- ется в настоящее время только в Internet Explorer 4.0, то следует использо- вать свойство navigator при создании страницы, которую можно будет про- сматривать с помощью различных браузеров. Оба свойства возвращают оди- наковые данные, включая имя и версию клиента. ( Примечание J В данном разделе свойства и объекты clientinformation и navigator ис- ' пользуются попеременно. Во всех случаях оба свойства и объекта предостав- ляют одинаковую информацию. Используя объект clientinformation или-navigator, программа может быть выполнена в зависимости от производителя и версии браузера. Если вы просто создаете программу для обхода ошибки или неподдерживаемого эле- мента в одном браузере, то проверка на клиентской стороне работает хоро- шо. Но переговоры на клиентской стороне, которые приводят к загрузке новых страниц, требуют многочисленных обращений к серверу. Если вы разрабатываете страницы для просмотра в различных браузерах, то эффек- тивнее передавать корректные страницы сразу, па основе указанного заго- ловка. Информация о производителе клиентского компьютера Перечисленные ниже четыре свойства объекта navigator представляют вер- сию и название клиента: □ appCodeName П appVersion О appName О userAgent Браузеры Internet Explorer и Netscape Navigator поддерживают одинаковый общий формат для свойства appVersion. Свойство appVersion возвращает версию клиента в следующем формате: clientversion [platform; information [; extraInformation}) В Netscape Navigator поле platform содержит название платформы, на кото- рой работает браузер. В Internet Explorer версий 3.0 и 4.0 строка compatible возвращается как значение платформы, а действительное название плат- формы записывается в поле extralnfonnation. В Netscape Navigator значение в поле information указывает уровень шифро- вания продукта. Например, для международной версии возвращается значе- ние 1, которое предоставляет более низкий уровень безопасности, чем вер- сия для U.S. (данное отличие обусловлено ограничениями на экспорт из
Глава 4. Окно браузера 125 U.S). Версия U.S. возвращает в данном поле значение U. Internet Explorer возвращает номер версии в поле information. Поле extrainformation может возвращать название платформы или бильд- номер требуемой операционной системы. Internet Explorer использует дан- ное поле для возвращения подробной информации о платформе. В зависи- мости от платформы данное поле может быть использовано Netscape Navigator. Поля в свойстве appversion организованы в согласованном формате. Про- грамма может различать клиентов путем анализа данного свойства. В табл. 4.2 перечислены значения, возвращаемые Internet Explorer и Netscape Navigator для платформы Microsoft Windows в свойствах appCodeName, appName И appVersion. Таблица 4.2. Значения свойства appversion для разных браузеров Browser appCodeName appName appVersion Microsoft Internet Explorer 3.0 Mozilla Microsoft Internet Explorer 2.0 (compatible; MSIE 30A; Windows 95) Microsoft Internet Explorer 4.0 Mozilla Microsoft Internet Explorer 4.0 (compatible; MSIE 4.0; Windows 95) Netscape Navigator 2.01 Mozilla Netscape 2.01 (Win95; 1) Netscape Navigator 3.0 Mozilla Netscape 3.0 (Win95; 1) Netscape Navigator 4.0 Preview 1 Mozilla Netscape 4.0b 1 (Win95;l) Свойство userAgent содержит строку пользовательского агента HTTP (Hyper- text Transfer Protocol), который определен в запросе HTTP. Строка пользова- тельского агента представляет собой объединение значений свойств appCodeName И appversion, разделенных КОСОЙ чертой: appCodeName/appVersron. Свойство appVersion Приведенный ниже код разделяет свойство appversion на базовые компо- ненты, которые затем добавляются в объект navigator как свойства. <HTML> <HEAD> <Т1ТЬЕ>Версия приложения</Т1ТЬЕ> <SCRIPT LANGUAGE="JavaScript">
126 Часть I. HTML и программирование сценариев // Запуск версии. function getVersionlnfo() { var version = navigator.appVersion; // Помещение открывающей скобки " (". var iParen = version.indexOf("0}; // Версия клиента указывается перед открывающей скобкой "(". navigator.clientversion = version.substring(0, iParen — 1); var information = new Array(); // Автоматически разделяет оставшиеся значения и помещает их в массив. information = version.substringfiParen + 1, version.length — 1).split ; // Первое значение представляет собой название платформы, navigator.platformlnfо = information[0); // Второе значение является информационным полем, navigator.information - information[1]; /* Третье значение представляет собой дополнительную информацию, которая может быть равна null в зависимости от браузера и платформы. */ navigator.extraInformation = information[2]; • } getVersionlnfo(); </SCRIPT> </HEAD> <BODY> <H1> Информация клиента </Н1> <Р>Код для разбора свойства appVersion.</Р> <SCRIPT LANGUAGE-»" JavaScript”» // Вывод информации. document.write("PlatformTnfo: ” + navigator.platforminfo + "<BR>”); document.write("Client Version: " + navigator.clientversion + ”<BR>"); document.write("Information: " + navigator.information + "<BR>"); document.write("Extra Info: " + navigator.extraInformation + "<BR>") ; </SCRIPT» </BODY> </HTML>
Глава 4. Окно браузера 127 Окна и объект navigator Объект navigator не используется совместно всеми загруженными экземп- лярами окна. Каждое окно имеет собственный экземпляр объект navigator. Хотя почти во всех случаях информация, представленная объектом navigator, одинакова для каждого окна, данное разделение имеет большое значение. По соображениям безопасности, если экземпляр страницы на- страивает объект navigator, то доступ к нему может иметь только данный экземпляр. В приведенном выше коде информация клиента была разделена на много- численные свойства, которые были добавлены непосредственно в объект navigator. Данные свойства доступны только для объекта navigator связан- ного окна. Ссылка на определяемые пользователем свойства объекта navigator другого окна будет возвращать значения undefined, как будто они не существуют. Установки пользователя Объект navigator обеспечивает доступ к информации о том, поддерживает ли браузер пользователя Java и cookies. Поддержка Java Чтобы определить, поддерживается ли Java на стороне клиента, объект navigator использует метод javaEnabled. Данный метод возвращает значение Boolean, которое определяет, может ли компьютер клиента отображать ап- плеты Java. Используя метод javaEnabled, можно написать сценарий, который вставляет апплет или отображает сообщения для пользователя: «SCRIPT LANGUAGE="JavaScript"> if (navigator.javaEnabledO) document.write("«APPLET NAME=demo CODE=demo.class ” + "WIDTH=50 HEIGHT=50x/APPLET>”); else document.write("<B>This page cannot run with Java disabled." + </SCRIPT> Поддержка cookie Internet Explorer 4.0 содержит свойство cookieEnabled, которое определяет, поддерживает ли клиент cookie. Cookie позволяют сохранять небольшое ко- личество информации, которая связана с текущей URL или доменом на
128 Часть I. HTML и программирование сценариев машине пользователя. Некоторые пользователи не хотят, чтобы на их ло- кальном жестком диске сохранялась какая-либо информация и поэтому от- ключают данный элемент браузера. Свойство cookieEnabied содержит логи- ческое значение Boolean, которое указывает, отключил ли браузер данную поддержку. Используя это свойство, вы можете реализовать индивидуаль- ную модель повеления, которая не использует cookie клиентской стороны, если оно недоступно. К сожалению, Internet Explorer 3.0 и Netscape Navigator 4.0 не поддерживают свойство cookieEnabied. Поэтому данный метод нельзя использовать во всех случаях, чтобы определить, активизирован ли прием cookies на клиентской машине. Новые свойства объекта navigator Объект navigator поддерживает ряд новых свойств, которые вы можете ис- пользовать, чтобы адаптировать документ для различных пользователей. Эти свойства приведены в таблице 4.3. Таблица 4.3. Новые свойства объекта navigator Свойство Описание cpuClass Тип CPU. Значение для процессора Pentium равно х86 systemLanguage Язык по умолчанию для системы. Для американского англий- ского значение равно en-us userLanguage Язык по умолчанию пользователя. Для американского англий- ского значение равно en-us platform Текущая операционная система пользователя. Для Microsoft Windows 95 значение равно Win32 appMinorVersion Вторая цифра в номере версии браузера. Значение для Internet Explorer 4.0 равно 0 onLine Логическое значение, определяющее, читает ли пользователь страницу в оперативном режиме
Глава 5 ,л„:. - г- Управление окном и фреймом В данной главе показано как создавать, управлять и осуществлять переход между окнами, модальными диалоговыми окнами и наборами фреймов. С помощью динамического HTML можно перемещать, изменять размер окон и прокручивать их содержимое. Программа может различными спосо- бами открывать HTML-документы в собственных окнах и манипулировать созданными экземплярами браузеров. Программа также может разделять окно на области, которые называются фреймами (frame), и манипулировать каждым фреймом как независимым окном. В главе рассмотрены следующие темы: □ Манипулирование окном. В главе 4 были введены события, которые воз- никают, когда пользователь взаимодействует с окном. В данном разделе обсуждаются методы, предоставляемые объектом window для перемеще- ния, изменения размера и прокручивания окна документа. □ Создание новых окоп. В данном разделе обсуждается создание профамм для манипулирования окнами. Объект window может быть использован для создания новых экземпляров окна браузера, а, следовательно, и соз- дания новых объектов window. Кроме того, объект window представляет методы, которые позволяют создавать множество диалоговых окон и окна справочной системы в формате HTML. Диалоговые окна полезны для вывода уведомлений пользователя, запроса ввода пользователем простых строк и запроса ответов на простые вопросы "да/нет". Вы можете также создать индивидуальные модальные диалоговые окна и файлы справки, содержание которых находится в других HTML-документах. □ Манипулирование наборами фреймов. В этом разделе представлен кол HTML для создания набора фреймов и вводится семейство 11 cUnefto.I, КО- торое обеспечивает доступ к индивидуальным фреймам. Каждый фрейм является экземпляром объекта window, так что объектная модель окон
130 Часть I. HTML и программирование сценариев также применима ко всем фреймам. Все методы, которые используются для манипулирования окнами, также могут быть использованы для ма- нипулирования фреймами. □ Рассмотрение специальных событий. В данном разделе введены методы обработки межфреймовых и межоконных событии. В разделе показано, как в одном окне написать обработчик событий, который будет обраба- тывать события в другом окне. Манипулирование окнами Объект window представляет методы для перемещения, изменения размера и прокручивания окна. Все три операции могут быть выполнены относитель- но текущего состояния окна или нового абсолютного положения посредст- вом пары методов для каждой операции, перечисленных в табл. 5.1: Таблица 5.1. Методы объекта window Метод Манипулирует Описание moveBy(offsetTop, offsetLeft) Окном Смещает окно на опреде- ленное расстояние (изме- ряемое в пикселах) moveTo(top, left) Окном Перемещает окно таким образом, что верхний ле- вый угол оказывается в указанном месте (коорди- наты которого указаны в пикселах) resizeBy(offsetwidth, offsetHeight) Окном Изменяет размер окна на определенную величину (из- меряемую в пикселах) resizeTo(width, height) Окном Изменяет размер окна до указанного значения (в пик- селах) scrollBy(offsetHorizontal, offsetvertical) Документом Прокручивает документ на определенную длину (в пик- селах) scrollTo(horizontal, vertical или scroll(horizontal, vertical) Документом Прокручивает документ до определенной позиции (из- меряемой в пикселах; мето- ды scrollTo И scroll ЯВ- ЛЯЮТСЯ вэамоэаменяемыми)
Глава 5. Управление окном и фреймом 131 В столбце Манипулирует указан объект (физическое окно или текущий до- кумент), к которому применяется метод. Обычно методы окна, которые вы- зываются внутри фрейма, применимы к текущему окну, ио методы переме- щения или изменения размера являются исключениями из этого правила. Методы всегда применимы к содержащему их окну. Поэтому вызов одного из этих четырех методов представляет собой то же самое, что и вызов мето- да в самом верхнем окне, как показано ниже: top.теthodName Свойство top описано в разделе "Манипулирование наборами фреймов” ниже в данной главе. Данное свойство объекта window всегда возвращает самое верх- нее окно в иерархии документов. Методы перемещения и изменения размера имеют ограничения, запрещающие им перемещать окно за пределы экрана или уменьшать его до такого размера, что оно будет невидимым. Методы про- кручивания манипулируют документом в окне, в котором вызван метод. Методы прокручивания соответствуют свойствам scrollTop и scrollLeft, пред- ставленным в свойстве body документа, которые были описаны в главе 9. Вызов мето- да scrollTo аналогичен присвоению новых значений в пикселах данным свойствам. Прокручивание окна Метод scroll (и эквивалентный метод scroirro) может быть использован для прокручивания документа до выбранного местоположения, используя координаты ху. Координаты ху определены в пикселах, относительно верх- него левого угла документа. Это означает, что scroll (0, 0) всегда прокручи- вает верхний левый угол документа на экране. Метод scroll завершает прокручивание по достижении конца документа. Например, если значение передаваемого аргумента vertical слишком вели- ко, то метод scroll не будет возвращать ошибку, а просто прокрутит ниж- нюю часть окна до нижней границы экрана. Невозможно создать код, кото- рый будет прокручивать последнюю строку документа за пределами экрана. При прокручивании документа в окне возникает событие onscroll. Данное событие генерируется независимо от того, является ли прокручивание ре- зультатом выполнения метода scroll или прокручивания документа пользо- вателем вручную. Нс следует писать программы, которые учитывают положение маркера по- лосы прокрутки, даже если учитываются ширина и высота документа, по- скольку при различных разрешениях экрана и в различных операционных системах шрифты мо<ут воспроизводиться по-разному, как по-разному мо- жет определяться и размер документа. Вместо этого лучше написать общую программу, которая проверяет наличие определенных изменений состояния. Например, в ответ на событие onscroll программа может прямо проверить,
132 Часть I. HTML и программирование сценариев находится ли элемент на экране, а не определять местоположение в доку- менте на основе положения маркера полосы прокрутки. Число браузеров, которые поддерживают метод scroll, превышает число браузеров, поддерживающих метод scrollTo. Метод scrollTo был введен для обеспечения совместимости с методами перемещения и изменения размера. Создание самопрокручивающегося окна Приведенный ниже код демонстрирует использование таймера для создания документа, который прокручивается автоматически. Данный код демонстри- рует использование метода scroll и учитывает размер документа. В этом примере текст прокручивается аналогично прокручиванию с помощью встроенного элемента Marquee. <HTML> <HEAD> <TITLE> Автоматически прокручивающееся окно </Т1ТЬЕ> <SCRIPT IANGUAGE="JavaScript"> var tScroll; var curPos = 0; function runTimerO ( curPos = document.body.scrollTop + 3; window.scroll(0, curPos); // Запуск с начала, если достигнут конец документа. if (curPos > document. body, scrollh'eight - do cumen t.body.с11en tHeight) window.scroll(0, C); tScroll = window.setTimeout("runTimer{);", 100); window.onload = runTimer; window.onunload - new Function("clearTimeout(tScroll)); </SCRIPT> </HEAD> •'.!— Атрибут стиля margin-bottom добавляет пустое пространство после последней строки текста. —> <BODY STYLE-"margin-bottom:350pt"> Contents to scroll </BODY> </HTML> Создание новых окон Динамический HTML представляет пять методов создания различных типов окон. Данные методы обеспечивают набор стандартных типов окон, а также индивидуальные окна в формате HTML и диалоговые окна.
Глава 5. Управление окном и фреймом 133 Могут быть созданы окна двух типов: модальные и немодальные. Модальное окно обычно является диалоговым окном, в котором пользователь должен сделать выбор для продолжения работы приложения. При отображении мо- дального окна сценарий в исходном окне останавливается и ожидает закры- тия диалогового окна. Немодальные окна работают независимо от текущего окна. Программа в немодальных диалоговых окнах выполняется независимо от других окон. Используя немодальные окна, вы можете создавать много- оконные приложения HTML. Методы создания модальных и немодальных окон перечислены в табл. 5.2. Таблица 5.2. Методы модальных и немодальных окон Метод Описание alert (message) Модальное. Отображает простое модальное диало- говое окно, содержащее определенное сообщение и кнопку ОК. Метод alert должен использоваться преимущественно для отображения сообщений о ошибках confirm (message) Модальное. Сходно с alert, но используется для задания пользователю вопроса. Данное диалоговое окно отображает текст с кнопками ОК и Cancel (Отмена). Нажатие кнопки ОК возвращает значение true (истина), а при нажатии кнопки Cancel возвра щается false (ложь) open([url [, name [, features (, replace]]]]) Немодальное. Открывает новый экземпляр браузе- ра, содержащий указанный адрес URL. Метод орел позволяет отключать или включать различные эле- менты окна prompt (message [, defaultText]) Модальное. Отображает диалоговое окно, которое запрашивает у пользователя строку. Необязатель- ный параметр defaultText используется для обес- печения значения по умолчанию для текстового ок- на. Если пользователь не может ввести строку и нажимает кнопку ОК, то возвращается пустая стро- ка. Если пользователь нажимает кнопку Cancel (Отмена) или Close (Закрыть), то возвращается зна- чение null showModalDialog (url [, arguments [, features]]) Модальное. Сходно с методом open, но отображает модальное диалоговое окно, содержащее указан-' ный URL. Сценарий может передавать аргументы в диалоговое окно, и поскольку модальные диалого- вые окна блокируют леток создания сценария, то диалоговое окно может определить возвращаемое значение
134 Часть I. HTML и программирование сценариев В следующих разделах подробно обсуждается использование данных ме- тодов. Немодальные окна Объект window использует метод open, который позволяет вам создавать новые немодальные окна. Новое окно представляет собой экземпляр браузера. Данный экземпляр имеет свою собственную историю, и навигация в нем осуществляется независимо от создавшего его окна. Метод open имеет следующий синтаксис: (windowobject = ] window.open([url [, name [, features [, replace])]]) Все параметры в методе open являются необязательными. Параметр url оп- ределяет исходную загружаемую страницу. Если данный параметр опущен, то в экземпляре браузера будет открыта пустая страница, что полезно, когда документ создается на основе сценария. Параметр name назначает имя окну, которое должно быть использовано, когда окно является целью (target) для последующих документов. Указание цели определяет место отображения документа, когда пользователь перехо- дит по ссылке. Атрибут target для ссылки может определять имя окна. Если окно для определенной цели не существует, то документ будет отображен в новом окне. Если цель нс определена, то новый документ будет отображен в текущем окне. Параметр name, а следовательно и атрибут target, могут со- держать только буквы, цифры и символ подчеркивания (_). Параметр features состоит из строки, которая определяет отображаемые элементы в новом окне, таким образом включая или отключая строки меню, панели инструментов и полосы прокрутки и определяя исходный размер окна. Эти элементы подробно обсуждаются в разделе "Элементы окна" ниже в данной главе. Параметр replace определяет обработку нового адреса URL в списке исто- рии окна. Если параметр replace опущен или имеет значение false, то ад- рес URL будет добавлен в конец списка. Если параметру присвоено значе- ние true, то URL заменяет текущий адрес URL в списке, если таковой име- ется. Если текущий адрес URL отсутствует, то данный адрес URL не будет добавлен вообще. Параметр replace используется преимущественно для уже открытых окон. Манипулирование новым окном Метод open возвращает ссылку на вновь созданное окно. Присвоив возвра- щаемое значение переменной, можно вызывать методы в это окно. Если указанное имя окна совпадает с именем существующего, то новое окно не создается, а содержание адреса URL отображается в существующем окне.
Глава 5. Управление окном и фреймом 135 Если вы не назначаете возвращаемое значение переменной, то не можете вызвать методы нового окна из программы. Можно, однако, обратиться к окну позднее, путем его повторного открытия, как показано в приведенном ниже коде: // Открыть окно без сохранения ссыпки на него, window.орел("myPlace.htm", "myPlace"); /* Загрузить новый документ в окно "myPlace" и сохранить ссылку на него. */ myPlace = window.open(”пг/Р1асе2.htm", "myPlace"); Данный код создаст только один экземпляр нового окна. Этот метод сходен с указанием в качестве цели окна нового документа. Модальные и индивидуальные диалоговые HTML-окна Как упоминалось выше, модальные диалоговые окна требуют ответа от пользователя для возобновления взаимодействия с браузером. Объект window представляет четыре метода, которые позволяют запрашивать пользователя с помощью модальных диалоговых окон. Три метода отображают простые встроенные диалоговые окна, а четвертый метод позволяет создавать инди- видуальные диалоговые окна в формате HTML. На прилагаемом компакт- диске содержится файл, который демонстрирует создание различных типов модальных диалоговых окон. Методы для встроенных диалоговых окон — alert, confirm и prompt — при- нимают строки message как аргументы. В JavaScript данные строки могут содержать разрывы строк, обозначенные cscape-символом \п. (В VBScript для обозначения разрыва строки используется chr(l3)). Ниже приведен пример сообщения alert со множеством строк: alertfYou entered invalid values on fields:\nName\nUser"); Метод showModalDiaiog используется для создания индивидуальных диалого- вых окон, которые могут отображать HTML-файлы. Внутри диалогового ок- на объектная модель немного отличается от традиционной объектной моде- ли окна, поскольку диалоговое окно является не полным экземпляром брау- зера, а средством просмотра документа HTML. Модальное диалоговое окно отличается от стандартного окна браузера по следующим параметрам: □ Отсутствует возможность навигации. (Нажатие ссылки приведет к откры- тию документа по данному адресу URL в новом окне браузера). □ Содержание внутри диалогового окна нельзя Выделить. Модальные диалоговые окна предназначены для отображения сообщений, которые требуют ответа и для запроса информации от пользователя. Подоб-
136 Часть I. HTML и программирование сценариев но встроенным методам prompt и confirm, индивидуальные модальные диа- логовые окна могут возвращать информацию в браузер. При создании индивидуальных модальных диалоговых окон вы всегда должны указывать кнопку закрытия. Если кнопка закрытия будет опущена, то диалоговое окно может быть закрыто только путем нажатия кнопки Close (Закрыть) в верхнем правом углу окна. Для создания кнопки закрытия ис- пользуйте тип кнопки Submit, так что кнопка будет вести себя как кнопка по умолчанию. Приведенный ниже код создает кнопку ОК, которая закры- вает диалоговое окно: CINPUT TYPE=SUBMIT VALUE="OK" STYLE="Width:5em" ONCLICK="window.close();"> Отображение индивидуальных диалоговых окон Первый и последний аргументы метода showModaiDiaicg в сущности пред- ставляют собой те же аргументы, что и в методе open. Первый аргумент оп- ределяет отображаемый адрес URL, а последний определяет набор элемен- тов отображаемого окна. Второй аргумент отличается и принимает не имя, а любую переменную, включая массив, и передает се в диалоговое окно. Дан- ный аргумент позволяет приложению передавать информацию в диалоговое окно. Можно определить возвращаемое значение для метода showModaiDiaicg, на- значив определенное свойство диалогового окна. Данное свойство может принимать любой тип переменной, которая возвращается в вызвавшее при- ложение. Обмен информацией с диалоговым окном Информация, обмен которой осуществляется с диалоговым окном, отражена в объектной модели диалогового окна. Копия переменной, которая опреде- лена как второй аргумент метода showModaiDiaiog, представлена в диалого- вом окне как свойство dialogArguments. Свойство returnvalue представлено для передачи информации обратно в вызвавшее приложение. Когда диало- говое окно закрывается, значение данною свойства используется как воз- вращаемое значение для диалогового окна. Приведенный ниже код демон- стрирует доступ к аргументам, обмен которыми осуществляется с диалого- вым окном: <нтмь> <HEAD> <TITLE> Передача переменных </TITLE> </HEAD> <!-- При выгрузке диалогового окна возвращается значение в текстовом окне. —> <BODY ONUNLOAD="window.returnValue = document.all.ret.value;">
Гпава 5. Управление окном и фреймом 137 <P>You passed in the following value:</P> <P ALIGN-CENTER> CSCRIPT LANGUAGE-"JavaScript”> document.write(window.dialogArguments); </SCRIPT> <P>Enter a value to return to the application:</P> <P ALIGN=CENTER> CINPUT TYPE=TEXT ID-"ret" VALUE="Return"> CINPUT STYLE="width:5em" TYPE=SUBMIT VALUE="OK" ONCLICK=”window.close()"> c/BODY> </HTML> Данное диалоговое окно может быть вызвано с помощью следующей команды: showModalDialog("pass.htm”, "Pass this string to the dialog box.."); Создание диалогового окна About С помощью метода alert вы можете создать простое диалоговое окно About. Используя метод showModal Di a log, можно создать диалоговое окно About с элементами форматирования HTML. Приведенный ниже код отображает индивидуальное диалоговое окно About. Первый документ содержит кнопку About, нажатие на которую выводит на экран диалоговое окно About. <HTML> <HEAD> CTITLE> Демонстрация окна About c/TITLE> cSCRIPT LANGUAGE^'JavaScript"> function about() { // Отображение диалогового окна About. event.srcElement.blur(); window.showModalDialog("about.htm", "dialogwidth:25em; dialogHeight:13em") ) </SCRIPT> C/HEAD> <BODY> CINPUT TYPE=BUTTON VALUE="About” ONCLICK="about();"> </BODY> </HTML> Код диалогового окна About находится в файле about.htm: <HTML> <HEAD>
138 Часть I. HTML и программирование сценариев <TITLE>About Inside Dynamic HTML</TITLE> </HEAD> <BODY STYLE="text-align:center; font-size:75%; background:lightgrey"> <H2>Companion CD-ROM Version 1.0</H2> <H3>By Scott Isaacs</H3> <H4 STYLE="font-style:italic"> Демонстрация возможностей динамического HTML! </H4> <!— Вводимая кнопка представляет собой кнопку по умолчанию. —> <INPUT TYPE=SUBMIT STYLE="Width:5em" VALUE="OK" ONCLICK=”window.close()> </BODY> </HTML> Создание диалоговых окон ввода информации Метод prompt используется для ввода простой информации пользователем. Однако если требуется ввод большого объема данных, то использование ме- тода prompt неэффективно. Для передачи множества значений между диа- логовым окном и создавшим его окном можно использовать массив или объект. Приведенный ниже код демонстрирует, как запросить ввод значе- ний в нескольких полях и передать введенную информацию обратно в при- ложение: <HTML> <HEAD> <TITLE> Пользовательская информация </TITLE> <STYLE TYPE="text/css"> BODY (margin-left:lOpt; background:menu) </STYLE> <SCRIPT LANGUAGE--"JavaSCript"> function saveValuesO ( // Построение массива возвращаемых значений. var retVal = new Array; for (var intLoop = 0; intLoop < document.UserInfo.length; intLoop-и) with (document.Userlnfo[intLoop)) if (name != retViil [name] = value; window.returnvalue =• retVal; event.returnvalue = false; window.close(); ) </SCRIPT>
Глава 5. Управление окном и фреймом 139 </HEAD> <BODY> <!— Данная форма используется для группирования содержащихся эле- ментов управления в легкодоступный массив. —> CFORM NAME=”UserInfо"> CFIELDSET> cLEGEND>User Informationc/LEGEND> CP>User Name: CINPUT TYPE=TEXT NAME="User”> CP>Address: CTEXTAREA ROWS="3" NAME="Address"x/TEXTAREA> c/FIELDSET> C/FORM> cp STYLE="text-align:center"> CINPUT TYPE=SUBMIT STYLE»"width:5em" ONCLICK="saveValues();" VALUE="OK"> CINPUT TYPE=RESET ONCLICK="window.close ();" VALUE»"Cancel"> C/BODY> </HTML> Если приведенный выше код находится в файле Userlnfo.htm, то следующий сценарий будет отображать код в модальном диалоговом окне, затем выпол- нять цикл и передавать возвращаемые значения: CSCRIPT LANGUAGE»"JavaScript"> var vals = new Array(); vals = window.showModaiDiaicg("Userinfo,htm"); if (vals ! = null) { strOut = "Returned values:"; for (name in vals) strOut +» "\n" + name + " = ” + vals[name]; alert(strOut); ) </SCRIPT> На прилагаемом компакт-диске можно найти полный набор модальных диалоговых окон различных типов. Размер и положение диалогового окна Размер и положение диалогового окна определяются четырьмя свойствами диалогового окна: □ dialogLeft О dialogwidth □ dialogTop О dialogHeight Данные свойства определены в пикселах и допускают операции чтс- ния/записи. В любом случае диалоговое окно не может быть меньше, чем 100x100 пикселов и не может находиться за пределами экрана.
140 Часть I. HTML и программирование сценариев Создание просматриваемых модальных диалоговых окон Метод, используемый для преодоления невозможности навигации в модаль- ных диалоговых окнах, заключается в отображении квазидокумента. Этот квазидокумент содержит элемент iFrame, который ссылается на действи- тельный отображаемый документ. Элемент iFrame создает полный экземп- ляр браузера. Несмотря на то что этот метод работает, следует соблюдать меры предосторожности при его использовании. Модальные диалоговые окна не предназначены для навигации в Web. Элементы окна При создании нового окна с помощью метода open или showModalDialog вы можете определить набор элементов окна, используя необязательный третий параметр features. Строка features представляет собой список значений, которые включают или отключают различные возможности окна. Эти зна- чения управляют визуальным отображением окна. В приведенных табл. 5.3 и 5.4 перечислены элементы, доступные для данных двух методов. Таблица 5.3. Элементы метода open Элемент Значения Описание directories [yesfno]I[1(0] Отображает строку каталогов, которая обеспечива- ет быстрый доступ к различным Web-страницам height ' pixels Указывает исходную высоту окна браузера left pixels Указывает расстояние между окном браузера и левой границей рабочего стола location [yeslno]|[110] Отображает строку адреса menubar [yeslno]|[1|0] Отображает меню по умолчанию (индивидуальные меню в настоящее время не могут быть определены) resizable [yeslno]|[110] Определяет, можно ли изменить размеры окна scrollbars ' [yeslno]|(1|0] Отображает полосы прокрутки для документа status [yeslno]I[1Ю] Отображает строку состояния в нижней части экрана toolbar [yeslno]|[1|0] Отображает панель инструментов top pixels Указывает расстояние между окном браузера и верхней частью рабочего стола width pixels Указывает исходную ширину окна браузера Метод window.showModalDialog поддерживает немного отличный набор эле- ментов для индивидуальной настройки модального диалогового окна.
Глава 5. Управление окном и фреймом 141 Таблица 5.4. Элементы метода window. showModalDia Элемент Значения Описание border [thicklthin] Определяет толщину границы диалогового окна center [yeslno]|[1|0] Выравнивает по центру диалоговое окно dialogHeight Измерение CSS Указывает исходную высоту диалогового окна dialogLeft Измерение CSS Указывает левое положение диалогового окна dialogTop Измерение CSS Указывает верхнее положение диалогового окна dialogwidth Измерение CSS Указывает исходную ширину диалогового окна font CSS font Определяет шрифт по умолчанию для диало- гового окна font-family CSS font-family Определяет начертание шрифта по умолча- нию для диалогового окна font-size CSS font-size Определяет размер шрифта по умолчанию для диалогового окна font-style CSS font-style Определяет стиль шрифта по умолчанию для диалогового окна font-variant CSS font-variant Определяет замену шрифта по умолчанию для диалогового окна font-weight CSS font-weight Определяет значение шрифта по умолчанию для диалогового окна help [yeslno]|(1|0] Определяет необходимость отображения значка справки в строке заголовка maximize [yes|no]|(1|0] Определяет необходимость отображения кноп- ки разворачивания (восстановления) окна в строке заголовка minimize [yeslno]1[110] Определяет необходимость отображения кноп- ки сворачивания в строке заголовка На рис. 5.1 показано окно, созданное с помощью метода open. Строка features Определение списка пар feature-value, разделенных точками с запятой, по- зволяет создать строку features: (feature = value [; feature2 = value2... [; featuren = valuen]]]
142 Часть I. HTML и программирование сценариев ---Поле адреса — Панель инструментов - Строка меню П aboutiblank && У»*' HtHreJ} Htwne (•j U bavoiiie^ 'iric, u.am-jis L Панель каталогов Полоса прокрутки------ Рис. 5.1. Элементы окна, созданного с использованием метода open Для создания окна, которое не отображает некоторых элементов браузера, используйте следующий код: window.open("example.htm", "example", "toolbar=no; location=no; menubar=no; status-no; dircctories^no”'; Для элементов, которые могут быть отключены или включены, вы можете определить значения yes или по или 1 или о, или просто указать параметр для включения элемента. Например, все приведенные ниже операторы включают элемент menubar (строка меню): window.open"menubar-yes"); window.open("...”, "menubar-1"); window.open(”.."menubar"); ( Примечание ) Если необходимо обеспечить совместимость с существующими версиями браузеров, используйте разделенный запятыми список для строки features метода open. Точки с запятой в качестве разделительного знака поддержива- ются только в Internet Explorer 4.0. Значения по умолчанию Если вы создаете окно с помощью метода open, но не указываете строку features, то автоматически будет указан набор параметров по умолчанию. Если вы указываете строку features, в которой определены не все элемен-
Гпава 5. Управление окном и фреймом 143 ты, то неопределенные элементы примут значения в соответствии с уста- новками в исходном окне. Метод showModaiDiaicg не поддерживает элемен- ты браузера, такие как панели инструментов и строки меню, поскольку мо- дальные диалоговые окна сами по себе не являются экземплярами браузера. По умолчанию в модальных диалоговых окнах отображается только строка заголовка, строка состояния, окно Close (Закрыть) и значок помощи. Элементы модальных диалоговых окон и CSS Многие элементы модального диалогового окна тесно связаны со свойства- ми CSS, поскольку модальное диалоговое окно, в отличие от немодальных окон браузера, отображает одиночный документ, переход из которого в другие документы невозможен. Свойства font, font-size, font-weight, font-family, font-variant И font- style поддерживают те же значения, что и свойства CSS с такими же име- нами. Эти свойства, а также положение и размеры диалогового окна прямо соответствуют свойствам таблицы стилей, и их значения не могут быть из- менены таблицей стилей документа. Например, размер диалогового окна может быть установлен страницей при помощи метода showModaiDiaiog или HTML-документом, отображаемым в диалоговом окне. Страница, которая вызывает метод showModaiDiaiog, может использовать строку features для определения размера. HTML-документ, отображаемый в диалоговом окне, может определить размер, используя свойства CSS width и height. Эти значения заменяют, установки метода showModaiDiaiog. Для создания диалогового окна, которое определяет свой собственный размер равным 10 на 10 ет, используйте таблицу стилей, пока- занную на приведенной ниже HTML-странице: <нтмь> <HEAD> <TITLE>10-by-10-Em Dialog Box</TITLE> <STYLE TYPE="text/css"> HTML (width:Idem; height:Idem) </STYLE> </HEAD> <BODY> Данный пример создает диалоговое окно размером ld-by-ld-em. Em представляет собой относительную единицу, которая легко адаптируется к различным размерам шрифтов. </BODY> </HTML> Свойство opener Окно, созданное другим окном, может обратиться к нему посредством свой- ства opener. В Internet Explorer 4.0 это свойство допускает операции чте-
144 Часть I. HTML и программирование сценариев ния/записи и может быть повторно назначено окну высшего уровня. В Internet Explorer 3.0 это свойство было предназначено только для чтения. Свойство opener используется для вызова методов, представленных окном, которые создают новый экземпляр браузера. Закрытие окна Окна, созданные с помощью кода, могут быть закрыты с использованием объектной модели. По соображениям безопасности пользователь должен подтвердить закрытие исходного окна браузера. Метод close используется для закрытия связанного с ним окна: window.close(); // Закрывает текущее окно. Пользователь может закрыть окно, к которому обращается или которым ма- нипулирует сценарий. По этой причине закрытое окно не является полно- стью разрушенным. Его свойство closed будет все еще доступно для пользо- вателя п сценариев. При описании окна, которое использует свойства или методы второго окна следует сначала проверить существование второго ок- на, как показано ниже: // Проверка того, что окно tnyWindow закрыто. if (!tnyWindow. closed) { // Код, который выполняется, если окно открыто. ) else ( // Код обработчика ошибок ) Создание диспетчера окон Когда документ в браузере создает новое окно, единственной ссылкой на него является переменная, возвращаемая методом open. Объектная модель не содержит семейство открытых окон. Подобное семейство было бы полез- но, например, если бы вы захотели выяснить существование определенного окна или изменить адрес URL окна. Приведенный ниже код показывает, как реализовать собственное семейство windows, содержащее ссылки на все окна, которые были открыты текущим документом. Данное семейство аналогично семейству frames, которое обсу- ждается в следующем разделе. Семейство windows доступно только в течение времени жизни документа и автоматически удаляется, когда пользователь переходит на другую страницу. Следующий пример определяет метод, названный createWindow, который открывает окно и добавляет ссылку на семейство windows. С помощью этого
Глава 5. Управление окном и фреймом 145 семейства можно определять, открыто ли окно, изменять его содержание или закрывать окно. Когда документ выгружается, то все окна, созданные е использованием метода createwindow, автоматически закрываются. <HTML> <HEAD> <TITLE>Window Manager</TITLE> CSCRIPT LANGUAGE=”JavaScript"> // Создание массива для хранения ссыпок на дочерние окна. /* Каждый член данного массива будет окном объекта, созданного ниже с использованием метода createwindow. */ var windows = new Array О; function newWindow(url, wname) ( // Конструктор для окна /* Данная функция может быть вызвана только функцией createwindow, которая приведена ниже. */ var features = if (null != arguments[2)) features = arguments[2); return window.open(url, wname, features); ) function createwindow(urJ, wname) ( // Добавление окна в семейство окон, var features = arguments[2) == null ? arguments[2]; windows[wname] = new newWindow(url, wname, features); J function closewindows() ( // Закрытие всех окон, открытых методом eiddWindow. /* Для закрытия окна вызывается его метод close. */ /* Данная функция может быть вызвана в ходе события onunload для автоматического закрытия всех открытых окон. */ for (w in windows) if ((windows[w].closed) windows[w].close(); } /* Приведенные ниже две функции демонстрируют использование методов createwindow и closewindows. ♦/ function listwindows() ( // Перечисление окон с указанием Wx текущих состояний. var swin = "Window List\n"; for (w in windows)
146 Часть I. HTML и программирование сценариев swin += w + ":" + ((windows[wj.closed) ? "Closed": "Open") + ”\n"; alert(swin); } function openSampleWindows() ( // Открывает два окна. createWindowfcloseme.htm", "Childwindowl”); createWindow("closeme.htm", "ChildWindow2"); } </SCRIPT> </HEAD> <BODY ONUNLOAD="closeWindOws();"> <Hl»Window Manager</Hl> <FORM> <INPUT TYPE=BUTTON ONCLICK="openSampleWindows();" VALUE-"Add Windows"> CINPUT TYPE=BUTTON ONCLICK="listWindows();" 1 VALUE="List Windows"» CINPUT TYPE=BUTTON ONCLICK="clOseWindows();" VALUE="Close Windows"» с/FORM» c/BODY» C/HTML» Данный диспетчер окон работает хорошо для именованных окон. Если вы создаете несколько окон, используя метод createWindow, но передаете пус- тые строки для их имен, то диспетчер окон отслеживает только последнее созданное окно. Манипулирование наборами фреймов Наборы фреймов поддерживались еще в Netscape Navigator 2.0 и Microsoft Internet Explorer 3.0. Наборы фреймов (frameset) представляют собой особый тип HTML-документа, который используется для разделения окна браузера на области, которые называются фреймами. Наборы фреймов наиболее ши- роко используются для отображения меню или других механизмов навига- ции в документах и фреймах или для представления статического заголовка страницы. На рис. 5.2 показан набор фреймов, который отображает четыре панели: панель с оглавлением и информационными панелями вверху и внизу дан- ной панели, а также панель с текстом документа. Таблица с содержанием документа содержит список ссылок, представляющих документы. Когда вы щелкаете по ссылке, в правом фрейме отображается соответствующий до- кумент.
Глава 5. Управление окном и фреймом 147 Inside Dynamic HTML • Microsoft Internet Explorer HL’ £ti.i Vjf-vv Цо ЯПЯЕЗ Inside Dynamic HTML Table of Contents l. .bib • Fundamentals of HTML Scripting * Dynamic HTML Event Model ® The Browser Window • lliwdtw and Frame Management Part II Document Structure... wwxymwHebHTMl.cotn copynght 1997 by Scott I saacc Chapter 5 Window and Frame Management Illis’ ;,h jj. ter shows you how to create, man.irjr. я'»! navigare between multiple wind ле inocW ’dialogboxes, arid Camesctr V’;th Dynamic HTML, your cirtipis can move, retue, and scroll windows Lour r.-.>de can open HTML documents hi their own windows in several different ways and manipulate die multiple browser instances created. It can also paragon fee window into multiple i egions called frames arid mariipulrite each Same as an independent window. S-l My Coo ;• I' Рис. 5.2. Окно, содержащее три фрейма в левой части и фрейм с документом справа В данном разделе сначала вводятся элементы HTML для создания докумен- тов с фреймами, а затем описывается объектная модель для манипуляции с ними. Каждый фрейм представляет собой отдельный объект window, доступ к которому и ссылка на который могут быть установлены из другого фрейма. Создание наборов фреймов Первым шагом при создании набора фреймов является определение распо- ложения фреймов. Набор фреймов может разделить экран на ряд прямо- угольных областей, каждая из которых содержит свой собственный HTML- документ. Тег <frameset> заменяет тег <body> в HTML-документе и используется для разделения экрана. Внутри элемента Frameset находятся теги <frame>, кото- рые указывают область для каждого документа. Наборы фреймов могут быть вложены один в другой для упрощения разделения экрана на горизонталь- ные и вертикальные столбцы. ( Примечание Internet Explorer 3 0 не делает различия между концепциями набора фреймов и документом, содержание которого находится в теле документа (body contents), несмотря на то, что данные концепции должны были быть независи- мыми. В Internet Explorer 3 0, если страница состоит из набора фреймов и тела документа, то тело документа воспроизводится как фрейм позади набора фреймов. Эта модель больше не поддерживается в Internet Explorer 4.0 и никогда не поддерживалась в Netscape Navigator, и поэтому ее не следует применять.
148 Часть I. HTML и программирование сценариев Синтаксис набора фреймов приведен ниже: <FRAMESET COLS="..." ROWS="..."> <FRAME SRC="..." NAME="..."> </FRAMESET> Атрибуты cols и rows принимают в качестве аргументов список значений, разделенных запятыми, которые используются для разделения экрана. Так, приведенный ниже набор фреймов разделяет экран на четыре равные области: <FRAMESET COLS="50%, 50%" ROWS="50%, 50%"> </FRAMESET> Если эти значения не определены, то набор фреймов содержит только одну строку и один столбец, которые занимают все окно. Для заполнения областей используется тег <frame>. Число фреймов должно быть равно числу строк, умноженному на число столбцов. В данном приме- ре набор фреймов должен состоять из четырех фреймов: <FRAMESET COLS="50%, 50%" ROWS="50%, 50%"> <FRAME SRC="fl.htm"> <FRAME SRC="f2.htm"> <FRAME SRC="f3.htm”> <FRAME SRC="f4.htm"> </FRAMESET> IQ Frameset with Four Flames Microsoft Internet... £3]] Fie £dt У’***’1 fio Fevortes Thefilen.htm contains this j document. f2.htm , , . , . v; . , f3.htm i'' I"W f4.htm Фреймы в наборе распространяются по горизонтали и затем вниз по вер- тикали. Приведенный выше код HTML разделяет браузер на четыре области, содержащие HTML-файлы, как показано на рис. 5.3. Рис. 5.3. Набор четырех фреймов Не требуется, чтобы число фреймов совпадало с указанным числом строк и столбцов. Если вы укажете слишком много элементов Frame, то допол- нительные элементы будут загружены, но не будут видны на экране. Если вы укажете слишком мало элементов Frame, то некоторые панели появятся внутри документов. Приведенный ниже код демонстрирует метод, позволяющий указывать до- полнительный фрейм, который не будет отображаться. Данный фрейм мо-
Гпава 5. Управление окном и фреймом 149 жет включать в себя содержание, управление которым будет осуществляться индивидуальной программой. <FRAMESET COLS="50%, 50% ”> <FRAME SRC=”f1.htm”> <FRAME SRC=”f2.htm”> <FRAME SRC="hidden.htm"> </FRAMESET> Фрейм, содержащий файл hiddcn.htm. не отображается па экране, поскольку первые два фрейма полностью занимают экранное пространство. В файле hidden.htm могут находиться только сценарии или другие элементы, которые используются для написания сценариев. Наборы фреймов также могут быть вложены друг в друга с помощью двух методов: □ Одиночная ячейка может быть разделена на дополнительные строки или столбцы путем определения другого набора фреймов. □ Документ, загружаемый в фрейме, может содержать набор фреймов, ко- торый дополнительно разделяет экран. Для использования первого метода в примере на рис. 5.-3 с целью разделе- ния нижнего правого фрейма на два столбца создайте приведенный ниже код HTML: <FRAMESET COLS=”50%, 50V ROWS=”50%, 50V> <FRAME SRC="fl.htm“ NAMF.= fl> <FRAME SRC="f2.htm" NAME=f2> <FRAME SRC="f3.htm” NAME=f3> <FRAMESET COI.S="50%, 50% "> <FRAME SRC="f4.htm" NAME=£4> <FRAME SRC="f5.htm" NAME=f5> </FRAMESET> </FRAMESET> В данном примере любой из документов (начиная с fl.htm и заканчивая f5.htm) может содержать другой набор фреймов, который в свою очередь делит экран. Если документ внутри фрейма содержи) другой фрейм, то вы можете изменить число и расположение фреймов путем изменения данного документа. Этот метод будет рассмотрен более подробно в разделе "Уста- новка целей фреймов" ниже в данной главе. Используя вложенные фреймы, можно легко изменить расположение фреймов. Для создания только строк или столбцов требуется указать только атрибут rows или cols. Также возможно более сложное управление расположением элементов на странице путем использования процентных значений атрибу- тов rows и cols. Значения для каждой строки или столбца могут представ-
150 Часть I. HTML и программирование сценариев лять значение в пикселах, а вместо цифры может быть указана звездочка (*). Звездочка устанавливает использование всего оставшегося пространства. Для создания набора фреймов, в котором ширина первого столбца составля- ет 50 процентов ширины экрана, ширина второго столбца равна одной трети оставшегося пространства и ширина третьего столбца равна оставшейся об- ласти экрана, используйте приведенный ниже код: <FRAMESET COLS="50%, *, 2*"> <FRAME SRC="fl.htm" NAME=fl> <FRAME SRC="f2.htm" NAME=f2> <FRAME SRC=”f3.htm” NAME=f3> </FRAMESET> Размеры фрейма и полос прокрутки По умолчанию размер фреймов может быть изменен и поддерживается про- крутка фреймов. Для фиксации размера и отключения возможности прокру- чивания фрейма могут быть добавлены два атрибута документа: noresize и scrolling. Атрибут noresize фиксирует текущий размер фрейма, a scrolling имеет три действительных значения, которые перечислены в табл. 5.5. Таблица 5.5. Значения атрибута scrolling Значение Описание auto Отображает полосы прокрутки только при необходимости yes Всегда отображает полосы прокрутки no Никогда не отображает полосы прокрутки, даже если содержание не помещается на экране Приведенный ниже код демонстрирует несколько вариантов применения атрибутов scrolling и noresize: <FRAMESET COLS=”50%, 50%" ROWS=”50%, 50%"> <FRAME SRC="fl.htm" NORESIZE> <FRAME SRC="f2.htm" SCROLLING="yes"> <FRAME SRC=”f3.htm" SCROLLING="no" NORESIZE> <FRAME SRC=”f4.htm" SCROLLING="auto"> </FRAMESET> Фреймы без границ В Internet Explorer 3.0 и Netscape Navigator 3.0 (эыла введена возможность создания фреймов без границ (borderless frames) (то есть, фреймов без окру- жающих их рамок. — Прим, перев.). Фреймы без границ отображают много-
Глава 5. Управление окном и фреймом 151 численные страницы без границ и каких-либо элементов, разделяющих эк- ран, что позволяет легко создавать привлекательные страницы. Атрибут border определяет толщину границы. Фреймы без границ создаются путем установки значения 0 для атрибута border тега <frameset>, что равно- сильно созданию прозрачных границ. В наборе свойств доступны три дополнительных свойства, которые обеспе- чивают большую управляемость границами. Атрибут framehorder определяет, будет ли граница нарисована как объемный фрейм. Атрибут framespacing подобно атрибуту border, устанавливает толщину границы. Полученная в результате толщина границы будет равна значению framespacing плюс тол- щина объемных границ, если они присутствуют. Атрибут bordercolor опре- деляет цвет границы фрейма. Поддержка браузеров низкого уровня Браузеры, не поддерживающие наборы фреймов, при попытке загрузки страницы отображают пустой документ. Для вывода содержания страницы с помощью устаревшего клиента в HTML 4.0 определен тег «noframes Эле- мент NoFrames может содержать действительное содержание тела документа, которое будет проигнорировано браузерами, поддерживающими фреймы, и будет отображено примитивными браузерами. Данный метод работает, по- скольку браузеры низкого уровня не понимают теги <frameset>, <frame> и <noframes>. Они просто проигнорируют их и отобразят содержание элемента NoFrames. Браузеры, поддерживающие наборы фреймов, проигнорируют со- держание элемента NoFrames. Пример документа с набором фреймов приве- ден ниже: <нтмь> <HEAD> <TITLE>Frameset Example«/TITLE> </HEAD> «FRAMESET COLS="50%, 50%” ROWS-"50%, 50%"> «FRAME SRC="fl.htm"> «FRAME SRC="f2.htm”> «FRAME SRC="f3.htm"> «FRAME SRC="f4.htm"> </FRAMESET> <NOFRAMES> Для просмотра данного узла, пожалуйста, используйте браузер, который поддерживает фреймы, click <А HREF="noframes.htm">here</A> for a no-frames version. </NOFRAMES> </HTML> Рекомендуется всегда включать в документ с набором фреймов комментарии без фреймов. Содержание без фреймов может быть просто инструкцией, как
152 Часть I. HTML и программирование сценариев в приведенном выше коде, или представлять собой отдельную Web-стра- ницу. Содержание элемента NoFrames может включать ссылки и другие дей- ствительные элементы кода HTML. Следует указывать минимальные ком- ментарии для пояснения, чтобы пользователь понимал, почему Web-узел не отображается. В противном случае пользователь, работающий с примитив- ным браузером не видя содержания страницы, может больше не вернуться на данный Web-сайт. Элемент NoFrames также может быть использован в теле документа. Напри- мер, набор фреймов может предоставлять панель перехода обратно в глав- ный документ, но браузеры, которые не поддерживают фреймы, не будут отображать панель при выводе на экран содержания главного документа. Вы можете ввести более простую панель перехода в элемент NoFrames главного документа, как показано в приведенном ниже примере: <НТМЬ> <HEAD> <TITLE>Navigation Example</TITLE> </HEAD> <BODY> <NOFRAMES> <!— Данное содержание отображается только в браузерах, не поддерживающих фреймы. Добавьте ниже дополнительную панель перехода. —> <Р> <А HREF="home.htm">Home Page</A> <А HREF="search.htm">Search Page</A> </P> </NOFRAMES> Здесь должно находиться содержание документа. <NOFRAMES> <!— Добавьте сообщение в конце документа. —> <Р> Для просмотра данной страницы следует использовать браузер, поддерживающий фреймы. </NOFRAMES> </BODY> </HTML> Данный метод работает корректно в Internet Explorer версий 3.0 и более поздних. Метод не работает в Netscape Navigator, поскольку Navigator в на- стоящее время отображает содержание элемента NoFrames. Встроенные фреймы Браузер Internet Explorer версии 3.0 и более поздних версий может создавать встроенные фреймы (inline frames). Встроенный фрейм находится внутри тела документа, а не внутри набора фреймов, и предоставляет возможность оди-
Глава 5. Управление окном и фреймом 153 ночному документу содержать другие независимые документы на странице. Встроенный фрейм функционально сходен с фреймом в наборе фреймов. Он поддерживает назначение целей (targeting) и разрешает пользователям пе- ремещаться внутри фрейма независимо от родительского документа. Использование встроенного фрейма сходно с внедрением объекта с помо- щью тега <object>. Приведенные ниже две инструкции HTML внедряют до- кумент: «IFRAME SRC="banner.htm" WIDTH=500 HEIGHT=500x/IFRAME> «OBJECT TYPE=”text/html” DATA="banner.htm" WIDTH=500 HEIGHT=500> </OBJECT> Главное отличие между двумя данными инструкциями заключается в том, что элемент iFrame может впоследствии быть установлен в качестве цели подобно фрейму в наборе фреймов. В целом, элемент iFrame должен быть использован для определения пользовательского интерфейса, обеспечиваю- щего возможности навигации на странице, а объект object должен быть ис- пользован для включения содержания документа. Оба элемента внедряют файл banner.htm в документ, но только элемент iFrame обеспечивает воз- можности навигации внутри собственного окна. Элемент iFrame представляет собой контейнер, содержание которого игно- рируется другими браузерами, поддерживающими iFrame. Поэтому вы може- те определить альтернативное содержание элемента iFrame для браузеров, которые не поддерживают iframe, аналогично тому, как вы используете элемент NoFrames для браузеров, не поддерживающих фреймы. «IFRAME SRC="banner.htm" WIDTH=500 HEIGHT=500> «Р> Ваш браузер не поддерживает элемент IFrame. </Р> </IFRAME> Добавление элементов сценариев Сценарии в документе с набором фреймов должны быть определены в эле- менте Head документа до первого элемента Frameset, как показано в сле- дующем примере. Браузеры могут игнорировать сценарии, которые появля- ются внутри или после элемента Frameset. <HTML> <HEAD> <TITLE>With Framesets, Script Location Is Important«/TITLE> «SCRIPT LANGUAGE3"JavaScript"> /* Данный сценарий будет выполняться,чпоскольку он находится перед элементом Frameset. * / </SCRIPT> </HEAD>
154 Часть I. HTML и программирование сценариев <FRAMESET ROWS="*"> <FRAME SRC="foo.htm"> <SCRIPT LANGUAGE="JavaScript"> // Сценарии, указанные после тега <ERAMESET>, будут игнорироваться. </SCRIPT> </FRAMESET> </HTML> Установка фреймов в качестве целей перехода Определение имени фрейма сходно с установкой имени окна. Имя исполь- зуется с целью определения цели для ссылки. Когда ссылка указывает на фрейм или окно, то она заменяет текущее содержание фрейма или окна но- вым документом. Только индивидуальные фреймы, включая фрейм, содер- жащий набор фреймов, могут быть указаны в качестве цели ссылки. Доку- мент замены может иметь любой тип MIME, поддерживаемый браузером, включая набор фреймов, который дополнительно разделяет экран. Это обеспечивает метод, который представляет режим одновременного обновле- ния нескольких фреймов. Ниже приведен пример простого набора фреймов, который разделяет экран па два фрейма: <HTML> <HEAD> <TTTLE>Main Docuinent</TITLE> <BASE TARGET="fContent"> </HEAD> <FRAMESET COLS="300, *"> <FRAME SRC=”menu. htrn" NAME=”fMenu"> <FRAME SRC="contents.htm” NAME="fContent”> </FRAMESET> </HTML> Файл contents.htm, показанный ниже, отображается в правом столбце и мо- жет самостоятельно представлять другой набор фреймов. В процессе нави- гации в правом фрейме может отображаться новый документ или новое оп- ределение набора фреймов. <HTML> <HEAD> <TITLE>Contents</TITLE> </HEAD> <FRAMESET ROWS=”20%, *”> <FRAME SRC="welcome.htm"> <FRAME SRC="home.htm"> </FRAMESET> </HTML>
Глава 5. Управление окном и фреймом 155 Поиск целевого фрейма При назначении фрейма в качестве цели используется определенный алго- ритм определения результирующего окна для документа. Данный алгоритм важен, так как несколько фреймов могут совместно использовать одно имя. Местоположение документа с указанной целью определяется путем поиска в наборе именованных окон и фреймов. Если определены стандартные ключевые слова, то документ отображается в данном фрейме. Например, тор отображает новый документ в окне, parent заменяет родительский фрейм, a self заменяет текущий документ. Для це- ли с другим именем все фреймы, встроенные фреймы и окна просматрива- ются в следующем порядке: 1. Текущий фрейм. 2. Все подфреймы текущего фрейма, затем все подфреймы данных под- фреймов и так далее. 3. Прямой предок текущего окна и затем его подфреймы, подфреймы его подфреймов и так далее. 4. Следующий прямой предок и все его подфреймы и так далее по цепочке до окна высшего уровня и его подфреймов. 5. Именованные окна, открытые текущим окном в произвольном порядке. Если совпадения не найдены, то открывается новое окно в качестве цели для URL. Сценарии для наборов фреймов Обращение к наборам фреймов и написание для них сценариев осуществля- ется посредством семейства frames, которое содержит все фреймы, опреде- ленные набором фреймов. Семейство frames в окне содержит все дочерние фреймы документа. Все фреймы являются объектами window, которые пред- ставляют ту же объектную модель, что и одиночные окна. Семейство frames создается на основе иерархии документа, а не видимой иерархии. Поэтому видимая иерархия не может быть явно определена с ис- пользованием самого семейства. Например, данный HTML-документ разде- ляет экран на две строки: верхняя строка является одиночным фреймом, а нижняя разделена на два столбца. <нтмь> <HEAD> <TITLE> Вложенные фреймы в документе </TITLE> </HEAD> <FRAMESET ROWS="50%, 50% ">
156 Часть I. HTML и программирование сценариев <FRAME SRC="top.htm" NAME="topRow"> <FRAMESET COLS="50%, 50% "> <FRAME SRC="bleft.htm” NAME="bottomLeft”> <FRAME SRC="bright.htm" NAME="bottomRight"> </FRAMESET> </FRAMESET> </HTML> Семейства frames, представленное для окна, содержащего приведенный выше документ, располагает фреймы в следующем порядке: topRow bottomLeft bottomRighL Несмотря на то что фреймы вложены друг в друга, семейство frarr.es уста- навливает их в исходном порядке. Если один из документов, на который ссылается набор фреймов, содержит другой набор фреймов, то образуется иерархия документов. Каждый доку- мент определяет свои собственные дочерние элементы и каждое дочернее окно может также определить собственные дочерние окна. Предположим, что файл top.htm является документом с набором фреймов: <HTML> <HEAD> <TITLE> Вложенный документ, который является набором фреймов </Т1ТЪЕ> </HEAD> <FRAMESET COLS-"40%, *"> <FRAME SRC-tleft.htm NAME="nostLeft”> <FRAME SRC=tright.htm NAME="nestRight"> </FRAMESET> </HTML> Семейства теперь расположены в иерархическом порядке, поскольку доку- мент в фрейме topRow содержит вложенный набор фреймов, который в свою очередь содержит два дополнительных документа: topRow nestLeft nestRight bottomLeft bottomRight Семейство документа высшего уровня включает те же элементы. Тем не ме- нее обращение к высшему фрейму возвращает вложенное семейство:
Глава 5. Управление окном и фреймом 157 top. frames.length // 3 фрейма: topRow, bottomLeft, bottomRight top. frames["topRow"]frames.length //2 фрейма: nestLeft and nestRight top. frames["topRow"].frames["nestLeft"].length // 0: дочерние фреймы // nestLeft отсутствуют Фреймы как объекты window Каждый фрейм в семействе frames в действительности представляет собой объект window. Набор свойств, представленных в каждом фрейме, совпадает с набором, представленным окном высшего уровня. Свойства window, кото- рые обсуждаются в остальной части данного раздела, являются поэтому свойствами фреймов. Динамический HTML представляет три связанных свойства для ссылки на окно: self, parent и top. Свойство self всегда возвращает текущее окно. Свойство parent возвращает родительское окно в иерархии набора фреймов. Свойство top возвращает ссылку на окно высшего уровня в браузере. Если окно является окном высшего уровня, то свойство parent возвращает текущее окно. Поэтому работа цикла, который просматривает иерархию на- бора фреймов, прерывается, когда текущее окно становится родительским окном, а не когда родительское окно становится равным null. Приведенный ниже код просматривает иерархию набора фреймов, пока нс достигнет окна высшего уровня: var fParent = self; while (fParent != fParent.parent) ( fParent = fParent.parent; ) Подобный код определяет, является ли текущее окно окном высшего уровня в иерархии объектов: if (self == top) { // Высшее окно. Введите здесь необходимый код. ) else { // Документ находится в наборе фреймов. Введите соответствующий код. ) Неявное семейство frames Хотя семейство frames представлено в объекте window, оно не является в действительности отдельным свойством. Напротив, объект frames и объект window представляют один объект. Наличие свойства frames упрощает код и делает его более ясным.
158 Часть I. HTML и программирование сценариев Недостаток четкого разделения между объектами весьма важен. В JavaScript, когда свойство добавляется в объект window, оно также доступно посредст- вом семейства frames и наоборот. Поэтому ссылка на свойство frames не требуется. Например, приведенные ниже пары инструкций эквивалентны: // Определение числа фреймов, window.length; window.frames.length; // Обращение к фрейму topRow. window,topRow; window.f tames.topRow; // Обращение к первому фрейму в семействе. window[0]; window.frames[0]; Хотя отсутствует четкое различие между объектами, рекомендуется исполь- зовать семейство frames, когда вы явно ссылаетесь на связанные с фрейма- ми члены, и свойство window при использовании свойства в текущем окне. Данная методика помогает документировать код. Определение содержания фрейма Содержание фрейма обычно определяется отдельным HTML-документом. Атрибут src фрейма может содержать код HTML. Преимущество помеще- ния HTML в тег <frame> заключается в том, что фреймы заголовков могут быть определены как встроенные, как показано в следующем примере, что нс требует внешнего URL, Ценность данного метода заключается в том, что уменьшает число циклов обмена информацией с сервером. <HTML> <HEAD> -<TITLE> Фрейм, генерируемый JavaScript </TITLE> </HEAD> <FRAMESET ROWS="80, *”> <FRAME SRC="JavaScript:'<Hl>Welcome to My Home Page</Hl>'" NAME="header"> < FRAME SRC=”content , htm"> </FRAMESET> </HTML> Указание исходного содержания фрейма не оказывает влияния па его спо- собность функционировать в качестве цели. Данный метод может быть да- лее обобщен для большинства атрибутов, которые используют URL. В главе 9 показано, как использовать JavaScript для атрибута ИНЕЕ ссылки. В против - ном случае, префикс VBScript: может определить содержание с помощью VBScript.
Глава 5. Управление окном и фреймом 159 Анализ иерархии набора фреймов Приведенный ниже код демонстрирует иерархию документа для любого на- бора фреймов. Данный код просматривает иерархию окна в определенном экземпляре браузера и выводит на экран иерархию контейнеров документа. <HTML> <HEAD> <TITLE> Иерархия наборов фреймов </TITLE> </HEAD> <FRAMESET ROWS="60, *"> <FRAME SRC="frames.htm"> <FRAME SRC="anyDocument.htm" NAME="hierarchy"> </FRAMESET> </HTML> Данный файл представляет собой набор фреймов высшего уровня. В ниж- нем фрейме отображается документ, который должен быть проанализирован (файл anyDocument.htm, но вы можете указать любой документ по своему желанию). В верхнем фрейме отображается документ frames.htm, перечис- ленный следующим в списке, который состоит из кнопки и кода JavaScript. При нажатии кнопки программа создает отдельное окно, показывающее ие- рархию документа. Данный. пример находится на прилагаемом компакт- диске. <нтмь> <HEAD> <TITLE> Генератор иерархии наборов фреймов </TITLE> <SCRIPT LANGUAGE""JavaScript"> function drillFrames(doc, w) { doc.write(”<TR><TD>Name: " + w.name + ”<BR>“); doc.write("Location: " + w.location.href); for (var i = 0; i < w.frames.length; i++) ( doc.write("<TABLE BORDER WIDTH=100% CELLPADDING=3>"); drillFrames(doc, w.framesfi]); doc.write("</TABLE>"); } doc.write ("</TDx/TR>"); } function outputFrames() { var doc = window.open().document; doc.open(); doc.write("<Hl>Frameset Hierarchy</Hl>"); doc.write("CTABLE BORDER CELLPADD^NG=3>”); // Start at the sibling frame in the hierarchy. drillFrames(doc, parent.hierarchy); doc.write("</TABLE>");
160 Часть I. HTML и программирование сценариев doc.close{); ) </SCRIPT> </HEAD> <BODY> <FORM> CINPUT TYPE=BUTTON VALUE="Walk" ONCLICK="outputFrames(); "> </FORM> </BODY> </HTML> Определение расположения набора фреймов Семейство frames представляет иерархию документа в браузере, но нс выво- дит параметры физического разделения экрана в каждом наборе фреймов. Эта информация представлена объектом document. Объект document имеет семейство ail, которое представляет каждый элемент в документе. Исполь- зуя семейство all, вы можете определить порядок фреймов и наборов фреймов. Объект document и семейство all обсуждаются в часта И. Программирование эле- мента Frameset обсуждается в главе 9. Все ли фреймы загружены Наборы фреймов также представляют событие onload в окне набора фрей- мов. Событие onload возникает, когда все фреймы внутри набора фреймов завершают загрузку. Поэтому любая инициализация, которая требует взаи- модействия между фреймами в наборе фреймов, должна осуществляться данным обработчиком событий. Кроме того, документ с набором фреймов представляет свойство readystate, которое может быть использовано для выяснения текущего состояния каж- дого фрейма п окна. Пока происходит загрузка фреймов, значение данного свойства равно interactive, а после загрузки всех фреймов его значение из- меняется на complete. Свойство readystate может быть использовано как флаг для проверки того, что все фреймы были засужены. Свойство readyState и связанное событие onreadystatechanqe подробно обсужда- ются в главе 6. Моделирование браузера Ниже показано, как создать очень простой браузер, используя наборы фреймов. Данный HTML-документ устанавливает набор фреймов: <HTML> <TITLE> Демонстрация браузера на основе набора фреймов </TITLE> <FRAMESET ROWS=”60, *">
Гпава 5. Управление окном и фреймом 161 CFRAME NAME="browser" SRC="browser.htm"> CFRAME NAME="content" SRC=""> c/FRAMESET> </HTML> Следующий документ указывает файл browser.htm, который воспроизводится в верхнем фрейме. Верхний фрейм содержит кнопки Go (Переход) и Refresh (Обновить) и текстовое окно, в котором пользователь вводит адрес URL. Кнопки Forward (Вперед) и Back (Назад) добавлены для перемещения по списку истории. Данные кнопки моделируют те функциональные возмож- ности, которые доступны на панели инструментов большинства браузеров: <HTML> cHEAD> cTITLE> Панель браузера </TITLE> </HEAD> <BODY> <FORM NAME="BrowseBar" ONSUBMIT="parent.content.location.href = this.txtGo.value; return false;"> CINPUT TYPE=BUTTON VALUE="Back" ONCLICK="parent.content.history.back();"> CINPUT TYPE=BUTTON VALUE="Forward" ONCLICK^"parent.content.history.forward();"> CINPUT TYPE=BUTTON VALUE="Refresh" ONCLICK="parent.content.location.reload));"> CINPUT TYPE=SUBMIT VALUE="Go"> CINPUT TYPE=TEXT NAME="txtGo"> c/FORM> c/BODY> C/HTML> ( Примечание J Ограничения безопасности браузера могут воспрепятствовать работе кнопок Forward (Вперед) и Back (Назад), если включаемые документы находятся в разных доменах. В данном примере элементы управления помещены в элемент Form, для га- рантии совместимости с Netscape Navigator версий 2.0 и 3.0, который не может воспроизводить элементы управления, отсутствующие в элементах Form. Internet Explorer версий 3.0 и более поздних не имеет данного ограни- чения и может отображать и программировать» элементы управления, даже если они находятся за пределами форм.
162 Часть I. HTML и программирование сценариев Особые случаи событий Используя указатели функций JavaScript можно назначить обработчик собы- тий в одном фрейме или браузере для свойства события в другом фрейме. Этот мощный метод позволяет совместно использовать программу в разных документах, однако при этом также возрастает сложность кода. Объект event тесно связан с окном, в котором было сгенерировано событие. Поэтому даже если обработчик событий может находиться в документе другого фрейма, должен быть использован объект event фрейма, который сгенерировал событие. Это требует просмотра иерархии объектов от элемен- та, который сгенерировал событие до объекта event. Данный метод разрешает создавать гибкие и мощные программы, но он ог- раничен установками модели безопасности браузера. Например, страница не может назначить обработчики событий окна фрейма или браузера, которое содержит документ из другого домена. Без этого ограничения несанкциони- рованная страница могла бы получить доступ к событиям клавиатуры и от- слеживать ввод конфиденциальной информации. Более того, если пользова- тель покидает страницу, то все обработчики событий отключаются. Это со- гласуется с объектной моделью динамического HTML, в которой новая страница всегда открывается в совершенно новом состоянии. Метод назначения функции является наиболее эффективным способом за- хвата событий в другом фрейме. При этом не требуется создание дополни- тельного обработчика функции. Однако данный метод предоставляет доступ только к тому элементу, который сгенерировал событие: <SCRIPT LANGUAGE»"JavaScript”» function doClick() { /* Это обработчик событий нажатия кнопки документа в окне window?. */ /* Доступ к объекту события не может осуществлен непосредственно С использованием объекта события текущего окна. Напротив, следует обратиться к объекту события окна window?. Указатель this передается в документ, который сгенерировал событие. */ with (this.document.parentwindow.event) ( // Использование объекта события. -} } var window? = window.open("sample.htm"); /* Связывает обработчик событий окна window? с функцией doClick в данном документе. */ window?.body.onclick = doClick; </SCRIPT> Программирование событий, возникающих между фреймами, является основой примера Event Tutor в главе 3. Работа Event Tutor основывается на динамическом связывании событий выбранного документа и выводе строк в текущем окне.
Структура документа Глава 6. Документ HTML Глава 7. Семейства элементов документа Глава 8. Сценарии и элементы Глава 9. Программирование индивидуальных элементов Глава 10. Формы и внутренние элементы управления

Глава 6 Документ HTML Структура, содержание и стиль HTML-документа представлены посредством свойства document окна. Свойство document ссылается на объект, который содержит всю информацию о документе. Объект document, (документ) явля- ется наиболее важным и мощным объектом в объектной модели динамиче- ского HTML. С помощью данного объекта вес элементы, находящиеся в документе, могут генерировать события. Доступ к этим элементам и их из- менение возможно посредством сценариев, что позволяет создать динамиче- ский документ. Элементы в HTML-документе представлены семейством объекта document. Доступ к содержанию документа возможен посредством данных элементов и объекта TextRange. Оба метода позволяют обращаться к содержанию докумен- та и изменять его. Стиль документа представлен семейством stylesheets, обеспечивающим доступ к таблицам глобальных и связанных стилей, кото- рые связаны с документом. Обсуждение этих вопросов будет проведено в нескольких главах. В данной главе рассматриваются следующие вопросы: □ Ссылка на объект document. Объект document является свойством окна. Показано, как получить доступ к HTML-документу, находящемуся в те- кущем окне, а также к документам, которые отображаются в других окнах. □ Изменение цветов документа. Объект document содержит свойства для манипулирования цветом текста и фона на странице. Данные свойства совместимы с реализацией объектной модели в Netscape Navigator и Internet Explorer 3.0. □ Доступ к метаинформации о документе. Информация, извлекаемая во время загрузки документа, используется в объектной модели. Эта мета- информация включает исходный размер документа, дату создания файла и его последнего изменения. Кроме того, могут быть извлечены или на- значены все cookie, которые связаны с документом.
166 Часть II. Структура документа □ Изменение потока HTML. Объект document предоставляет методы мани- пулирования потоком HTML во время загрузки страницы. Эти методы работают только во время воспроизведения страницы на экране. Для из- менения страницы после загрузки используются отдельные объекты и методы. На рис. 6.1 показан объект document и семейства, которые содержатся внутри объекта. Рядом с названием ail elements семейства указан тег для содержа- щихся в нем HTML -элементов. <А NAME0 > «APPLET», «OBJECTS «IMG» <FORM> «IFRAME» <AHREF= >. <AREAHREF=...> «SCRIPT» Рис. 6.1. Семейства и соответствующие HTML-элементы style sneet objects объекта document Ссылка на объект document На объект document можно сослаться как на свойство объекта window (окно). Если вы ссылаетесь на документ без указания окна, в котором находится документ, то будет установлена ссылка на текущий документ. В приведен- ных ниже примерах даны ссылки на документ для получения его названия: document.title // Заголовок текущего документа. window.document.title // То же самое, но указана явная ссылка на текущее окно myPlace.document.title // Заголовок документа в окне MyPlace Ссылка MyPlace в данном примере должна бЪтть ссылкой на окно, которое возвращается методом open или именем фрейма в текущей иерархии набора фреймов.
Глава 6. Документ HTML 167 Независимо от того, содержит ли текущее окно набор фреймов или HTML- документ, объект document представлен полностью. По соображениям безо- пасности некоторые свойства могут быть недоступны для других доменов. Например, содержание документа доступно для страниц, которые совместно используют домен документа. Изменение цветов документа Одной из самых простых операций, которую можно выполнить с докумен- том, является изменение цветов фона и текста. Объект document представля- ет свойства, которые определяют цвета фона, текста и ссылок. В документе доступны следующие свойства цвета: aiinkcolor, bgcolor, fgCoior, linkcolor и vlinkColor. Свойство bgcolor управляет цветом фона документа, а свойство fgCoior управляет цветом текста по умолчанию. Для представления активных, просмотренных и непросмотренных ссылок используются три цвета. Ссылка — это довольно туманный термин, который в данном случае означает элемент Anchor, имеющий набор атрибутов href: <А HREF="myPage.HTM">This is a link.</A> Активной ссылкой является ссылка, которая находится в фокусе и обычно выделена другим цветом и окружена бледной пунктирной рамкой вокруг нее. Просмотренная ссылка — это ссылка, которую пользователь недавно по- сетил, а непросмотренная ссылка представляет ссылку, которая еще не была открыта. Одним из способов управления цветами документа является непосредствен- ная установка свойств документа. Вы можете установить цвета, используя атрибуты тега <body> или таблиц стилей. В случае использования тега <body> или атрибутов таблицы стилей код будет более цельным, а свойства цвета в объекте document будут поддерживаться большим количеством браузеров. В габл. 6.1 перечислены свойства цвета и соответствующие атрибуты тега <BODY>. Таблица 6.1. Свойства цвета и атрибуты тега <body> Свойство Атрибут Свойство Атрибут alinkColor AL INK linkcolor link bgColor bgColor vlinkColor vlink fgCoior text Таблицы стилей при установке цветов имеют более высокий приоритет, чем свойства документа или атрибуты тега <body>. Свойства документа всегда
168 Часть II. Структура документа будут отражать цвета, показанные на экране. Если цвет установлен с помо- щью таблицы стилей, то назначения свойств цвета документа будут проиг- норированы. Действительные значения цветов Все свойства цвета, включая представленные в элементах, принимают в качестве значения символьную строку, представляющую имя цвета или шестнадцатеричное значение RGB. Список действительных имен строк и их шестнадцатеричных эквивалентов можно найти на прилагаемом компакт- диске. Шестнадцатеричные значения RGB указываются в следующем формате: #RRGGBB R, G, В — это первые буквы трех английских названий цветов (Red — крас- ный, Green — зеленый и Blue — голубой). Каждый канал использует дейст- вительные шестнадцатеричные значения в диапазоне от 0 до #FF. Если вы обращаетесь к значению одного из этих свойств в документе или элементе HTML, то всегда получаете шестнадцатеричное значение, даже если первоначально указали название цвета. Например, установка свойства Red для строки возвращает значение #ffoooo. Однако свойства CSS (кас- кадных таблиц стилей) оставляют введенные значения без изменений, так что при установке свойства стиля red возвращается значение red. Выбор цвета HTML позволяет использовать большое количество символических имен для обозначения цвета. Цвета, представленные этими именами, часто слож- но представить, и определение цветовой гаммы может быть затруднено. Приведенный ниже код реализует селектор цветов, который помогает уста- | новить цвета фона и текста. Все параметры селектора цветов заключены в элементе Div, так что селектор цветов и его сценарии можно легко переме- щать и запускать без изменения других HTML-документов. <HTML> <HEAD> <TITLE> Селектор цветов на основе HTML </TITLE> <STYLE TYPE=”text/css"> TABLE {background:white) /* Установить одинаковый размер всех ячеек. */ TD {width:30pt; height:30pt; cursor:default) </STYLE> </HEAD> <BODY> <Hl>Color Selector</Hl>
Глава 6. Документ HTML 169 <!— Когда пользователь щелкает кнопкой мыши по ячейке, экран перерисовывается с учетом соответствующего цвета фона или текста. —> <DIV ONCLICK="colorSelector()"> <SCRIPT LANGUAGE^’JavaScгipt"> function colorSelector() { // На основе таблицы устанавливает соответствующий цвет. // Элемент srcElement является элементом, по которому производится щелчок мышью. if ("TD" == event.srcElement.tagName) if (document.all.Text.contains(event.srcElement)) document.fgColor = event.srcElement.bgColor; else if (document.all.Background.contains( event.srcElement)) document.bgColor = event.srcElement.bgColor; } </SCRIPT> <!— Для расширения данных таблиц добавьте ячейки в фоновую таблицу и/или таблицу цвета текста. Каждая ячейка состоит только из соответствующего цвета фона. --> <TABLE ID="Background" BORDER> <CAPTION>Background Color</CAPTION> <TR> <TD BGCOLOR=Blackx/TDxTD BGCOLOR=Redx/TD> <TD BGCOLOR=GreenX/TDXTD BGCOLOR=LightBluex/TD> <TD BGCOLOR=Yellowx/TD> </TR> <TR> <TD BGCOLOR=YellowGreenx/TDxTD BGCOLOR=Orangex/TD> <TD BGCOLOR=Navyx/TDXTD BGCOLOR=MagentaX/TD> <TD BGCOLOR=BrownX/TD> </TR> <TR> <TD BGCOLOR=Black></TDXTD BGCOLOR=Bluex/TD> <TD BGCOLOR=BurlywoodX/TDXTD BGCOLOR=Goldx/TD> <TD BGCOLOR=CyanX/TD> </TR> </TABLE> <TABLE ID="Text" BORDER> <CAPTION>Text Color</CAPTION> <TR> <TD BGCOLOR=Blackx/TDxTD BGCOLOR=Redx/TD> <TD BGCOLOR=Greenx/TDxTD BGCOLOR=LightBluex/TD> <TD BGCOLOR=BrownX/TD> </TR> <TR> <TD BGCOLOR=Whitex/TDXTD BGCOLOR-Blue></TD> •
170 Часть II. Структура документа <TD BGCOLOR=Burlywoodx/TDxTD BGCOLOR=GoldX/TD> <TD BGCOLOR=Cyanx/TD> </TR> </TABLE> </DIV> </BODY> </HTML> Селектор цветов работает только путем введения двух таблиц в элемент div и использования всплывания событий для выявления всех событий нажатия кнопки. Когда пользователь щелкает в элементе div, обработчик события нажатия кнопки проверяет, что событие нажатия кнопки возникло в ячейке одной из двух таблиц. Если щелчок был произведен в ячейке, то обработчик событий сначала определяет, находится ли ячейка в фоновой таблице или текстовой таблице, и затем устанавливает цвет соответствующего документа равным цвету выбранной ячейки. В приведенном выше коде содержится только часть доступных цветов, но выбор может быть легко расширен путем простого добавления дополни- тельных ячеек в таблицы цветов фона или цветов текста. Отражение атрибутов HTML как свойств Атрибуты всех элементов HTML в документе представлены как свойства в объектной модели. Вы можете установить значение атрибута в теге HTML или установить значение соответствующего свойства. Если выполнить оба действия, то отображение на экране будет соответствовать установкам сце- нария. Например, сценарий в приведенном ниже коде устанавливает цвет фона равным Red (красный), и последующая установка значения Blue (голубой) для соответствующего атрибута в теге <body> не сможет изменить выбранный цвет: <HTML> «SCRIPT LANGUAGE^'JavaScript"> document.bgColor = "Red"; </SCRIPT> «BODY BGCOLOR="Blue"> Установлен красный фон страницы. </BODY> </HTML> Доступ к метаинформации о документе ч Помимо обеспечения доступа к содержанию документа, динамический HTML представляет информацию, которая извлекается из документа но время его загрузки. Эта метаинформация включает исходный размер файла
Гпава 6. Документ HTML 171 документа и даты его создания, последнего изменения и последнего кэши- рования. Дата может быть использована, чтобы определить возраст докумен- та для активизации сценариев с целью предупреждения пользователя о том, что содержание документа устарело. Документ также представляет информацию о cookie клиента. Cookie являют- ся отчасти спорным элементом, поскольку они позволяют Web-узлу сохра- нять небольшие фрагменты информации на клиентской машине, к которым впоследствии узел может обращаться и обновлять их. Данная информация ограничена в том смысле, что доступ к данным имеют только те узлы, кото- рые создали эти данные. В документе также содержится информация о состоянии всех внедренных объектов, включая информацию о том, закончена ли загрузка документа или объекта. Эта информация необходима при написании сценариев, которые могут выполняться до того, как страница станет доступна пользователю. Размер файла Документ представляет свойство filesize, которое возвращает исходный размер документа в килобайтах. Возвращаемое значение представляет число байт в файле, который был загружен и не отражает изменений, которые могли быть внесены сценариями в документ. Заголовок Значение свойства title документа устанавливается в элементе Head сле- дующим образом: <HTML> <HEAD> <TITLE> Заголовок документа </TITLE> </HEAD> </HTML> Заголовок содержит стандартный текст. Он не может содержать элементы HTML. Свойство документа title возвращает содержание элемента Title как строку. Вы можете назначить повое значение данной строке для изменения названия, отображаемого в строке заголовка. В операционных системах с под- держкой окон этот заголовок, как правило, является заголовком окна. ( Примечание ) Netscape Navigator 3.0 и Internet Explorer 3.0 генерируют ошибку, когда страница пытается присвоить значение свойству title. Internet Explorer 4.0 устанавли- вает данное свойство доступным для чтения/записи.
172 Часть II. Структура документа Местоположение источника Документ использует два свойства, которые представляют местоположение источника страницы: location и url. Свойство location в документе являет- ся псевдонимом для свойства location окна — оба свойства возвращают объекты, которые представляют одинаковый набор свойств. Свойство location окна подробно обсуждается в главе 4. Свойство документа url является псевдонимом для свойства href в объекте location. Свойство url используется для обеспечения совместимости с ран- ними версиями браузеров. Свойство location окна или документа использу- ется для определения и изменения отображаемой в данный момент страни- цы. Дата Для любого документа могут быть указаны три даты: дата создания докумен- та, дата последнего обновления документа автором и дата последней загруз- ки документа в кэш. Эта информация представлена в документе посредст- вом следующих свойств: □ fileCreatedDate Л fileModifiedDate ИЛИ lastModified Л fileUpdatedDate Значение свойства fileCreatedDate (дата создания файла) очевидно из его названия. Остальные свойства обсуждаются в следующих разделах данной главы. Свойства fileModifiedDate и lastModified Свойства fileModifiedDate и lastModified содержат дату последнего изме- нения документа и могут быть использованы совместно со свойством cookie, чтобы определить, не был ли документ изменен с момента его по- следнего посещения пользователем. Internet Explorer 3.0 и Netscape Navigator поддерживают свойство lastModified, но они не поддерживают свойство fileModifiedDate. Internet Explorer 4.0 поддерживает новое свойство для обеспечения совместимости с другой метаинформацией, которая была вве- дена в динамический HTML. Приведенный ниже код выводит дату последнего изменения файла: <HTML> <HEAD> <TITLE> Дата последнего изменения </TITLE> </HEAD>
Глава 6. Документ HTML 173 <BODY» <P»Last Modified: <SCRIPT LANGUAGE="JavaScript"» document.write(document.lastModified); </SCRIPT> </P> </BODY» </HTML> Метод wri te используется для записи в поток доку Агента во время загрузки страницы. Данный метод весьма подробно обсуждается ниже в разделе "Запись кода HTML в по- ток " этой главы. Свойство fileUpdatedDate В ходе работы в сети файлы кэшируются на локальной машине пользовате- ля. Свойство fileUpdatedDate возвращает дату последнего обновления файла сервером. Используя данное свойство можно написать код, уведомляющий пользователя о том, что просматриваемая страница находится в кэше доль- ше установленного периода времени: CHTML» <HEAD> <TITLE>fileUpdatedDate Examplec/TITLE» <SCRIPT LANGUAGE^'JavaScript"» /* Период обновления (в днях) страницы. */ var intAge = 7; // Убедитесь, что страница была обновлена. if ("" != document.fileUpdatedDate) ( var dCreate = new Date(document.fileUpdatedDate); var dToday = new DateO; /* Расчет числа дней хранения страницы. getTime возвращает число миллисекунд за период, начиная с полночи (по Гринвичу (GMT) 1/1/1970 до указанной даты и времени. */ var intDays = Math.floor((dToday.getTime() — dCreate.getTime()) / (1000 * 60 * 60 * 24)); if (intAge < intDays) if (confirm("Your cached page is " + intDays + " day(s) old.Xn" + "Do you want to download a new page?")) // Обновление страницы с сервера, location.reload(true); ) </SCRIPT» C/HEAD»
174 Часть II. Структура документа <BODY> Содержание документа </BODY> </HTML> Тип MIME Свойство tnimeType возвращает MIME-тип документа. Для всех HTML- документов (включая наборы фреймов) свойство mimeType возвращает зна- чение Internet Document (HTML). Cookies HTML-страница имеет возможность сохранить небольшие объемы инфор- мации в специальном файле на клиентской машине. Данная информация называется cookie. Многие пользователи считают, что cookie представляет потенциальную опасность, так как позволяют странице записывать инфор- мацию на жесткий диск клиентской машины. Браузеры дают возможность отключить эту возможность. По этой причине не следует создавать Web- страницы, предполагая доступность cookie. Однако cookie полезны для ве- дения информации о состоянии, которая используется многими страницами на данном узле. В данном разделе будет показано, как использовать cookie и обеспечивать функции помощи для манипулирования ими. В конце раздела приведен пример, демонстрирующий использование cookie для создания счетчика по- сещений на клиентской стороне. ( Примечание Internet Explorer 3.0 не разрешает модифицировать cookie, если доступ к стра- нице был осуществлен посредством протокола file:. Это ограничение было сня- то в Internet Explorer 4.0. Чтение свойства cookie С одним документом или доменом может быть связано несколько свойств cookie. При чтении свойства cookie возвращается список, содержащий раз- деленные точкой с запятой пары имя-значение. Поэтому требуется процеду- ра, которая будет анализировать список cookie. JavaScript представляет неко- торые методы простого разделения подобных списков на массивы. Приве- денная ниже функция анализирует строку cookie п возвращает сс в виде массива, содержащего пары имя-значение: <SCRIPT LANGUAGE^’’JavaScript "> function parseCookie() {
Гпава 6. Документ HTML<75 // Разделение cookie. var cookieList = document.cookie.split(”; "); 11 Массив для каждого cookie находится в cookieList var cookieArray = new Array(); for (var i = 0; i < cookieList.length; i++) { // Разделение пар имя-значение. var name = cookieList[i].split("="); 11 Декодирование и добавление в массив cookie. cookieArray[unescape(name[01)1 = unescape(name[l)); > return cookieArray; ) </SCRIPT> Приведенный ниже код демонстрирует, как использовать массив cookie, возвращаемый функцией parseCookie(): var cookie; var cookies = parseCookie() ; // Вывод всех cookie. for (cookie in cookies) alertfcookie + ”=” + cookies(cookie]); 11 Проверка существования cookie по имени foo. if (null == cookies.foo) ( // Отсутствует cookie по имени foo ) Пары имя-значение, которые вы назначаете cookie, не могут содержать про- белов, запятых и точек с запятой. Все эти символы должны быть заменены на соответствующие escape-последовательности. JavaScript использует две функции, которые обрабатывают escape-последовательности: функция escape служит для замены символов на escape-последовательности в строке до ее назначения определенному cookie, а функция unescape используется для выполнения обратной операции при извлечении cookie. Сохраненный cookie всегда содержит дату истечения срока хранения, путь, домен и информацию безопасности. Вы можете указать данную информа- цию при создании cookie, но не можете извлечь ее. В этом заключается од- но из отличий между назначением значений cookie и извлечением cookie. Запись свойства cookie Значение свойства cookie представляет собой строковое значение в следую- щем формате: name=value; (expires=date; [path=path; [domain=domain [secure;]]]]
176 Часть II. Структура документа Пара имя-значение является единственным необходимым параметром при назначении информации cookie. Имя может быть любой действительной строкой, с которой связано значение. Указание пары имя-значение без ка- кой-либо дополнительной информации создает cookie, который сохраняется только в течение текущего сеанса браузера. Приведенный ниже код создает простой файл cookie, содержащий время и дату загрузки страницы: <SCRIPT LANGUAGE”"JavaScript”> var strLoaded = new Date(); document.cookie = "Loaded=" + escape(strLoaded); </SCRIPT> Назначение другого значения необязательно перезаписывает файл cookie — он будет перезаписан, только если вы используете то же имя. В приведен- ном выше примере имя Loaded повторно используется каждый раз при за- грузке страницы. В следующем примере добавление нового имени приводит к добавлению нового элемента в cookie. <SCRIPT LANGUAGE»"JavaScript"> document.cookie = "First=Hello; document.cookie = ”Second=Hello; alert(document.cookie); 11 First=Hello; Second=Hello </SCRIPT> Для того чтобы удалить cookie, необходимо определить дату истечения срока хранения. Для удаления создайте новый cookie, используя имеющееся имя и любое произвольное значение, но назначьте истекший срок хранения. При использовании данного метода cookie не может быть немедленно удален — файл останется на диске до тех пор, пока не будет перезагружен текущий экземпляр браузера. Дата окончания срока хранения cookie должна быть определена в системе времени по Гринвичу (GMT) в приведенном ниже формате: wkd, day Mon Year hh:mm:ss GMT Ниже приведен пример даты в требуемом формате: Sat, 28 Sep 1998 19:01:05 GMT В JavaScript простейшим способом преобразования в формат GMT является использование метода toGMTString, представленного объектом Date. Файлы cookie остаются на клиентской машине вплоть до момента оконча- ния срока хранения. При этом нет гарантии, что указание даты окончания срока хранения cookie позволит сохранить их на диске, поскольку существу- ет ограничение на число cookie, которые могут храниться на клиентской машине, и пользователь может в любой момент удалить файл cookie.
Глава 6. Документ HTML 1 // По умолчанию все файлы cookie сохраняются с указанием пути и домена, даже если данные значения явно не определены. Таким образом поддержи- вается безопасность для cookie. Доступ к cookie можно получить только с указанием пути и домена, в котором был создан cookie. Более того, при соз- дании cookie вы не можете указать произвольный домен. Данное ограниче- ние исключает возможность передачи секретной информации из одного до- мена в другой. Однако несколько страниц из данного домена могут совме- стно использовать один файл cookie. Использование cookie Cookie могут использоваться для создания индивидуальных страниц для пользователя. Приведенный ниже код показывает, как использовать cookie для учета числа посещений пользователем Web-страницы. Данный код ис- пользует функцию parsecookie, которая была рассмотрена ранее. <HTML> <HEAD> <TITLE> Счетчик с использованием cookie </TITLE> </HEAD> <BODY> <SCRIPT LANGUAGE="JavaScript"> // Данный код использует функцию parseCookie. function setCookie(visits) { /* Данная подпрограмма устанавливает cookie путем указания его значения равным числу посещений и определяет срок хранения равным 1 году, начиная с данного момента. */ var expireDate = new Dated; var today = new Date(); // Устанавливает будущую дату истечения срока хранения. expireDate.setDate(365 + expireDate.getDateО); // Сохраните число посещений. document.cookie = "Visits=" + visits + expires=" + expireDate.toGMTString() + // Сохранение настоящей даты и времени как даты последнего посещения. document.cookie = "LastVisit=" + escape(today.toGMTString()) + ”; expires=" + expireDate.toGMTString() + I if ("== document. cookie) ( // Инициализация cookie. setCookie(1);
1/В Часть II. Структура документа document.write("<H2>This is your first visit to our ” + "humble home page.</H2>"); } else ( // Анализ cookie, var cookies = parseCookie(); // Вывод сообщения Welcome Back (Заходите еще), и увеличение на единицу счетчика // посещений. document.write("<H2>Welcome Back! You have visited us " + cookies.Visits++ + " time(s)!</H2>”); document.write("<H3>Your last visit was on " + cookies.Lastvisit + ".</H3>"); // Обновление cookie. setCookie(cookies.Visits); } </SCRIPT> </BODY> </HTML> Родительское окно Точно так же, как вы перемещаетесь из окна в документ, вы можете воз- , вращаться из документа в содержащее его окно. Окно, содержащее доку- мент, представлено посредством свойства parentwindow. Данное свойство полезно при определении объекта-контейнера, когда доступен только объект document. Для доступа к окну из документа можно использовать два дополнительных свойства: script и frames. Свойство Script представлено для обратной со- вместимости с Internet Explorer 3.0 и больше не должно использоваться. Свойство frames возвращает семейство встроенных фреймов в документе. Это семейство frames возвращает окно, поскольку оно является псевдони- мом семейства frames окна, которое в свою очередь является псевдонимом объекта window. Манипулирование семействами подробно обсуждается в главе 7. Для прояснения взаимоотношений между данными свойствами приведен- ный ниже код демонстрирует несколько способов возвращения объекта window: window == self == window-frames == frames window.document.parentwindow == window.document.Script == window.document.frames
Гпава 6. Документ HTML 179 Доступность документа В процессе загрузки документ или внедренный объект проходят через четы- ре стадии: не инициализирован (uninitialized), загружается (loading), интерак- тивный (interactive) и загрузка завершена (complete). Свойство объекта ceadystate содержит текущее состояние объекта. Когда объект изменяет со- стояние, генерируется событие onreadystatechange. Используя данные инст- рументы в сценариях, можно установить поведение страницы в соответствии с четырьмя стадиями загрузки документа и внедренных объектов, а также определить реакцию на изменения в процессе загрузки. Наиболее важно то, что программа может не обращаться к не полностью загруженным объектам. В табл. 6.2 описаны стадии загрузки, через которые проходят документ и внедренные объекты. Таблица 6.2. Стадии загрузки документа Состояние Описание uninitialized Страница или объект еще не инициализированы. После начала загрузки осуществляется переход к состоянию загрузки loading Страница или объект находятся в состоянии загрузки interactive Пользователь может взаимодействовать со страницей или объек- том даже в процессе загрузки — например, якоря могут уже нахо- диться в активном состоянии и загруженные элементы могут на- чать генерировать события complete Страница или объект полностью загружены Когда начинается загрузка документа, документ сразу же переходит в со- стояние загрузки. Переход в интерактивное состояние наступает, когда браузер встречает первый элемент script, Body или Frameset. Документ пе- реходит в завершенное состояние, когда весь документ проанализирован и загружены все внедренные объекты. Свойство readyState Свойство документа readystate содержит строку текущего состояния доку- мента. Каждый внедренный объект имеет собственное свойство readystate, которое отражает его состояние. Поскольку документ перейдет в интерактивное состояние после запуска ка- кого-либо сценария, то сценарии документа могут получить только два зна- чения свойства readystate: interactive и complete. Сценарий в другом фрейме или окне может получить значение loading. Это произойдет, если сценарий обратится к свойству документа readystate в ходе анализа элемен-
180 Часть II. Структура документа та Head документа и перед обнаружением сценариев в элементе Head. Любой сценарий может получить одно из четырех значений readyState внедренного объекта. Обработчики событий JavaScript захватываются асинхронно в ходе анализа страницы. Такой обработчик может выполняться перед тем, как вся страни- ца будет загружена. Если обработчик выполняет операции, которые требуют, чтобы страница была полностью загружена, то обработчик может проверить значение свойства документа readyState перед продолжением обработки, как показано в приведенном ниже примере: <SCRIPT LANGUAGE»"JavaScript" EVENT="onclick" FOR="window"> if ("complete" == document.readyState) ( // Обработка события. ) else alert("This action is not available until the document " + "finishes downloading."); </SCRIPT> В противном случае обработчик может проверить значения свойства readyState только тех элементов, к которым ему необходим доступ. Обработчики событий VBScript захватываются на последнем шаге перед пе- реходом документа в состояние завершения загрузки. Поэтому обработчики, написанные на VBScript, не требуют проверки свойства документа readystatc — за исключением, конечно, случаев, когда обработчик обраща- ется к элементам в другом документе. Событие onreadystatechange Событие onreadystatechange возникает, когда изменяется состояние доку- мента или внедренных объектов. Данное событие может генерироваться большое число раз в ходе загрузки документа или элемента. Если вы связываете обработчика с событием документа onreadystatechange. то он нс будет связан, пока документ не перейдет в интерактивное состояние. Обработчик будет вызван только один раз — а именно при переходе доку- мента в состояние завершения загрузки. В данной ситуации событие onreadystatechange В сущности является псевдонимом ДЛЯ события onload окна и данные события могут генерироваться попеременно. Поскольку Internet Explorer 4.0 является единственным браузером, который в настоящее время поддерживает свойство onreadystatechange, то вы можете использо- вать данное событие, если хотите исключить совместимость с другими брау- зерами. Если требуется обеспечить работу с различными браузерами, то можно использовать событие onload.
Гпава 6. Документ HTML 181 Внедренные объекты в документе также запускают событие onreadystatechange. Например, элементы Object и IMG генерируют событие onreadystatechange. Для данных элементов программа может получить со- бытие во время нескольких переходов состояния, в зависимости от того, когда был использован обработчик событий. В целом, однако, не следует писать программы, которые зависят от переходов в любое состояние, за ис- ключением перехода в состояние завершения. Модификация потока HTML Первоначально объектная модель в Internet Explorer 3.0 не позволяла изме- нять содержание документа после воспроизведения страницы. С тех пор был представлен ряд методов для вывода HTML в потоке документа во время загрузки страницы или для генерации совершенно нового HTML-документа в другом фрейме или экземпляре браузера. Пример, приведенный выше в данной главе, который выводит дату последнего измене- ния исходного файла, показывает, как добавлять HTML в поток загружаемого доку- мента. Пример в главе 5, который создает диаграмму иерархии набора фреймов доку- мента, поясняет процедуру генерации завершенных документов. Методы добавления содержания в поток HTML в ходе его анализа и для генерации завершенных документов, перечислены ниже: □ write □ open □ writein □ close Объектная модель теперь обеспечивает доступ к потоку, но данные методы, тем не менее, очень полезны для генерации содержания при загрузке стра- ницы. Сценарии могут генерировать различные программы HTML в ответ на различные условия. ( Примечание ) Одним из нововведений в динамическом HTML является способность модифи- цировать содержание документа после его загрузки. Вы можете модифициро- вать документ, используя свойства и методы элемента Body и его дочерних элементов, или используя новый объект по имени TextRange. Изменение со- держания документа подробно обсуждается в части IV. Маркированные разделы Если вы знакомы с маркированными разделами (marked sections) SGML, то увидите, что сценарии, которые осуществляют запись в поток HTML, сход- ны с ними. Маркированные разделы позволяют браузеру использовать раз- личное содержание, в зависимости от определенного условия. Например, апплет Java, дополнительный модуль или изображение могут быть выведены
182 Часть II. Структура документа на экран в зависимости от поддержки данного элемента браузером. Однако генерация содержания с помощью сценариев имеет существенный недоста- ток, связанный с тем, что содержание документа не может быть предопре- делено и индексировано с помощью инструментов без оценки сценариев на странице. Запись HTML в поток Методы write и writein позволяют записывать код HTML в текущий поток во время загрузки документа или в другой поток, который был открыт с ис- пользованием метода open. В данной книге метод write используется в до- вольно редких случаях для вывода кода HTML в поток во время загрузки страницы. Аргументы, передаваемые методу write, всегда конвертируются в строки перед тем, как они будут выведены в документе. Метод writein сходен с методом write, но он присоединяет символ конца строки к концу строки. Чаще всего не имеет значения, какой используется метод, write или writein, поскольку символы конца строки игнорируются в потоке HTML. Символы конца строки и пробелы имеют значение только в трех случаях: □ В элементах PRE и ХМР, в которых остаются символы конца строки. О В элементах, которые не содержат HTML, таких как Script и Style. □ В потоках в MIME-типе, отличном от HTML. Не следует использовать методы write и writein в текущем документе после окончания загрузки документа, если только вначале не был вызван метод open, который очищает текущее окно документа и удаляет все переменные. Создание документов с помощью методов open и close Методы open и close документа позволяют создавать новые документы в других фреймах или окнах. Данные документы даже не должны быть напи- саны на HTML, поскольку метод open принимает в качестве аргумента идентификатор MIME-типа. Поэтому если известен формат изображения или другой тип документа, то изображение или тип документа могут быть выведены прямо в окне. । Приведенный ниже код демонстрирует использование методов open и close для вывода информации документа определенного окна в другом окне: function docinfo(win) { /* Создание диалогового окна About. */ var aboutWindow = window.open"Info", "toolbar=no; location=no; directories=no; width=375; " + "height=250; status=no; menubar=no; resizable=no"); var prop;
Гпава 6. Документ HTML 183 // Открытие потока в новом окне. aboutWindow.document.open(); // Вывод информации документа. aboutWindow.document.write("<H1>Document Information</Hl>"); for (prop in win.location) aboutWindow.document.write(prop + ” + self.location[prop] + "<BR>"); // Закрытие потока в новом окне. aboutWindow.document.close(); ( Примечание j Метод clear был представлен в Internet Explorer 3.0 для удаления содержания документа. Данный метод больше не используется, его поддержка в будущем сомнительна, и он ведет себя непредсказуемо в различных браузерах. Для удаления и генерации нойых документов применяются методы open и close. Запись сценариев в поток Сценарий может вставлять дополнительные сценарии в поток При исполь- зовании данного метода следует быть осторожным при закрытии сценарием элемента script, в который производится вставка. Сценарий должен вста- вить тег </script> как две связанные строки, как показано в приведенном ниже коде. В противном случае анализатор HTML будет считать, что тег завершает сценарий, который вы пишете, а не вставляемый сценарий. <SCRIPT LANGUAGE»"JavaScript"> // Пример динамической генерации сценария document.write("<SCRIPT LANGUAGE»'JavaScript’> x » 0; <" + "/SCRIPT>"); </SCRIPT>
Семейства элементов документа Объектная модель динамического HTML представляет структуру документа посредством набора семейств, которые используются объектом document. Семейства обеспечивают доступ ко всем элементам HTML, содержащимся внутри документа. Понимание взаимоотношений семейств с исходным ко- дом HTML и способов доступа к ним является ключом к программирова- нию HTML-документа. В данной главе будет показано, как манипулировать семействами элементов документа, а также как Microsoft internet Explorer 4.0 анализирует документ. Рассмотрим приведенный ниже короткий HTML-код: <нтмъ> <HEAD> < TITLE> Структура документа </Т1ТЬЕ> </HEAD> <BODY> < Н1>Overview</Н1> < P>Examining an HTML document</P> </BODY> </HTML> Объектная модель обеспечивает возможность доступа к элементам нтмъ, Head, Title, Body, Hl И Paragraph И, соответственно, ВОЗМОЖНОСТЬ изменения их атрибутов. Доступ к разметке, гак же как и другим аспектам документа, осуществляется посредством объекта document, введенного в главе 6. Объект document представляет семейство all, которое содержит все элементы доку- мента и несколько выбранных семейств, которые представляют подмноже- ство элементов документа. Например, семейство forms содержит только элементы Form. Кроме того, разработчики могут сами создавать семейства элементов документа.
Гпава 7. Семейства элементов документа 185 Возможность доступа к любому элементу в документе является ключевым нововведением в динамическом HTML. До появления динамического HTML сценарии могли манипулировать только набором элементов, который представлял интерес для разработчиков браузеров. Теперь Web-разработчики имеют возможность осуществлять полное управление страницей и могут вы- бирать элементы, представляющие для них интерес. Они могут выбирать элементы из семейства all и манипулировать набором элементов, обраща- ясь к ним как к одной группе, удаляя все ограничения и предоставляя уни- версальный доступ к документу. В данной главе рассмотрены следующие темы: □ Использование семейств. Каждое семейство в динамическом HTML со- вместно использует общий набор операций. Показано, как получить дос- туп к элементам внутри семейства, а также как создать индивидуальное семейство элементов. Поскольку принципы построения всех семейств в объектной модели динамического HTML совпадают, то раздел содержит большой объем базовой информации для манипулирования и использо- вания семейств. Остальные главы части II построены па этой информа- ции и показывают, как манипулировать отдельными элементами внутри семейств. □ Структура и семейства HTML. В данном разделе описывается механизм анализа и представления документа HTML с помощью основных се- мейств. В разделе обсуждаются также особенности анализа и раскрытия недействительных HTML-документов в объектной модели, что важно для понимания при программировании общих страниц, в которых недоступ- но управление структурой документа. Использование семейств В этом разделе внимание сфокусировано на использовании семейства all для доступа к элементам на странице. Семейство ап в объекте document со- держит все элементы, находящиеся в файле HTML. Манипулирование дан- ным семейством осуществляется посредством набора свойств и методов, ко- торые поддерживаются всеми семействами элементов. Свойства и методы определяют число элементов в семействе, обеспечивают доступ к индивиду- альным элементам и предоставляют возможность выбора элементов по типу из семейства. Примечание ) Поскольку все семейства совместно используют общий набор свойств и мето- дов, все члены, которые обсуждаются в данном разделе, могут быть использо- ваны с любым семейством элементов в документе.
186 Часть II. Структура документа Размер семейства Первой и наиболее фундаментальной операцией в семействе является опре- деление числа элементов в семействе. Число элементов возвращается свой- ством length. Так, пример документа в начале этой главы содержит шесть элементов: alert(document.all.length); //6 элементов Доступ к элементам Доступ к элементам в семействах осуществляется посредством метола item. Метод item использует в качестве аргумента порядковое положение или идентификатор строки, которые представляют атрибут name или id элемента. Когда вы указываете порядковый номер, помните, что во всех семействах отсчет начинается с нуля. Поэтому приведенный ниже код пересчитывает элементы в семействе ан: // Отображение имени тега для всех элементов. for (var i = 0, i < document.all.length, i++) alert(document.all.item(i).tagName); ( Примечание В цикле, подобном этому, который обращается к элементам семейства, выра- жение условия должно проверять, что значение индекса меньше, чем число элементов в семействе. Поскольку первый элемент в семействе имеет нулевой номер, то отсутствует элемент, индекс которого равен числу элементов семейства. В VBScript item является методом по умолчанию в семействах. Определение метода item необязательно при обращении к элементам. В JavaScript методы по умолчанию не поддерживаются. Однако все объекты представляют свя- занные массивы, что позволяет обращаться ко всем именованным элемен- там как к обычным элсмснгам массивов. Это означает, что все элементы в семействе также представлены как свойства в объекте, что позволяет обра- щаться к элементам по их порядковому номеру в основном массиве или по их символьному имени, или идентификатору (ID). Приведенный выше кол может быть переписан следующим образом: // Отображение имени тега для всех элементов. for (var i = 0, i < document.all.length, i++) alert(document.all[i].tagName); ( Примечание В JavaScript ссылка на массив осуществляется/: использованием квадратных скобок ([ ]). В VBScript, где вместо массива используется метод по умолчанию, в ссылках используются круглые скобки: msgbox(document.all(i).id) 1 VBScript
Глава 7. Семейства элементов документа 187 Атрибуты id и пате Выше была продемонстрирована ссылка на элемент только по его порядко- вому номеру. Ссылка на элементы может также осуществляться непосредст- венно, путем использования атрибутов id или палю, между которыми суще- ствует несколько различий. Атрибут id уникальным образом определяет элемент внутри документа. Атрибут name может быть совместно использован множеством элементов. Данный атрибут используется определенными эле- ментами и обычно имеет определенное значение. Например, для элемента в блоке формы атрибут пате используется в указываемом имени, а в кнопках- переключателях атрибут name используется для группирования кнопок. При назначении имен для программного доступа следует использовать ат- рибут id. Атрибут name должен быть зарезервирован для своего истинного использования на основании контекста элемента. Атрибут name может по- требоваться программе для Netscape Navigator, поскольку данный браузер в настоящее время не распознает атрибут id в элементах, которые не пози- ционированы с помощью CSS (Cascading Style Sheets — каскадные таблицы стилей). Атрибут name поддерживается в Netscape Navigator для доступа к элементу Form, фреймам и всем встроенным элементам управления. ( Примечание Для упрощения терминологии, начиная с этого момента термин именованный элемент будет обозначать элемент, который имеет установленное значение атрибута id или пате. Ссылка на именованные элементы В JavaScript атрибуты id или пате используются для ссылки на элемент тре- мя способами: используя метод семейства item, прямо, как свойство семей- ства или косвенно, как просмотр массива. Приведенные ниже примеры ил- люстрируют способы ссылок на элемент, значение атрибута id ИЛИ name КО- ТОРОГО равно myElement: document.all.item("myElement") document.al1.myElement document.all["myElement"] Ссылаясь на элементы, при помощи метода item или по индексу массива в семействе all, можно запросить элемент путем передачи переменной. Дан- ный метод полезен, поскольку не требуется заранее знать и вносить в про- грамму атрибуты id или name. Ниже приведен пример общего кода с пере- менной, которая содержит атрибут id: // Получение имени тега для элемента с определенным значением атрибута id. var retValue = window.prompt("Enter an ID:");
188 Часть II. Структура документа if (retValue != null) alert(document.all[retValue].tagName); Использование метода Item для возвращения семейства Атрибут элемента name в документе не обязательно должен быть уникаль- ным. Кнопки-переключатели в группе обычно совместно используют одно значение пате, как показано в приведенном ниже примере: <HTML> <HEAD> <TITLE> Группа кнопок-переключателей </TITLE> </HEAD> <BODY> <FORM> Name: CINPUT TYPE=TEXT NAME="YourName"XBR> CINPUT TYPE=RADIO NAME="Gender" VALUE="Male">Male CINPUT TYPE=RADIO NAME=”Gender" VALUE="Female">Female C/FORM> C/BODY> C/HTML> Поскольку значение атрибута name не обязательно должно быть уникаль- ным, то значение name, которое используется для поиска элемента семейст- ва, может совпадать более чем в одном элементе. При наличии нескольких совпадений результатом просмотра является подсемейство, содержащее все элементы с данным значением атрибута пате. Приведенные ниже примеры являются обращением к именованным элементам в приведенном выше коде: document.all["YourName"] // // document.all["Gender”] // document.all["Gender”].length // document.all["Gender"].item(O) // Окно ввода информации Input box (не является семейством) Семейство из двух элементов 2 Кнопка-переключатель Male Подсемейство строится на тех же принципах, что и все остальные семейст- ва. В частности, оно представляет свойство length и метод item. Элементы в подсемействе находятся в том же порядке, в котором они находились в ис- ходном семействе. Когда метод item возвращает подсемейство, можно передать второй пара- метр для выбора элемента в подсемействе. Например, обратиться к кнопке- переключателю Male можно следующим способом: document.all.item("Gender", 0) VBScript и JavaScript поддерживают ярлыки длЯ доступа к элементам в под- семействе без использования метода item. Например, приведенные ниже фрагменты кода обращаются к кнопке-переключателю Male:
Гпава 7. Семейства элементов документа 189 ’ В VBScript метод item используется по умолчанию. document.all("Gender", 0) // JavaScript использует доступ как к массиву document.all["Gender"][0] Документы с дублирующимися значениями id являются технически недей- ствительными, но разработчик может их использовать, а сценарии, которые обращаются к неизвестным документам в других фреймах или окнах, могут обнаружить их. Приведенный ниже пример кода содержит несколько эле- ментов со значением атрибута id, равным test: <HTML> <HEAD> <TITLE> Дублирующиеся ID </TITLE> </HEAD> <BODY> <H1 ID="test">Header 1</H1> <P ID=”test”>This is a paragraph. <P ID="test”>This is another paragraph. <INPUT ID=“test” NAME="foo”>This is a named Input box. </BODY> </HTML> Атрибуты id с дублирующимися значениями обрабатываются как дубли- рующиеся имена. Если сценарий ищет элемент по значению id и обнаружи- вает несколько совпадений с искомым id, то все элементы будут возвраще- ны как семейство. Приведенные ниже выражения обращаются к элементам в приведенном выше коде, которые имеют значение атрибута id, равное test: document.all["test"].length // 4 document.all.test.length // 4 (просмотр непосредственно по значению id) document.all.test.tags("Р").length // 2 document.all.test.item("test").length // 4 (избыточный код) Окно Input в приведенном выше коде интересно тем, что является частью семейства, возвращаемого по атрибуту item ("test"), и представлено инди- видуально в качестве элемента item ("foo”). Доступ к окну Input можно по- лучить посредством семейства элементов со значением атрибута id, равным test: document.all.test.item("foo").tagName // INPUT document.all.foo.tagName // Также INPUT Если значения атрибутов name и id элемента совпадают, то элемент, тем нс менее, появляется в семействе элементов со значением name или id только один раз. Элемент может существовать в семействе только в одном экземпляре.
190 Часть II. Структура документа Различие между семейством и элементом Когда программа обращается к элементу по значению name или id, то может быть возвращено семейство или элемент. Поэтому программа должна уметь различать, является ли возвращаемый объект элементом или семейством. В JavaScript свойство length возвращает null для отдельных элементов и число элементов для семейств. Свойство length возвращает null для отдель- ного элемента, поскольку оно в действительности не существует для объек- та — JavaScript автоматически добавляет свойство length в объект со значе- нием null по умолчанию. Приведенный ниже код позволяет проверить, что было возвращено — се- мейство или элемент: // Использование length if (null -- document.all("Gender"]•length) { // Одиночный элемент ) else { // Семейство ) Примечание Нельзя использовать length в VBScript для выявления различия между инди- видуальными элементами и семействами. Если вы попытаетесь это сделать, то VBScript сгенерирует ошибку, потому что данное свойство не существует для объекта элемента. Ссылка на неизвестные имена элементов Если метод item вызывается с использованием атрибутов пате или id, кото- рые не существуют в документе или еще не были загружены, то метод воз- вращает объект null: var el = document.all.item("foo"); if (null •=- el) alert("Please try again when the page is loaded."); else { 11 Операции с элементом foo. } Прямой доступ к именованным элементам Доступ к именованным элементам возможен посредством семейств. Кроме того, некоторые именованные элементы также представляют собой свойства документа или окна. Такие элементы добавляются в документ и окно ис-
Глава 7. Семейства элементов документа 191 ключительно в целях обратной совместимости. Рекомендуемым способом доступа к данным элементам является использование семейства all. При наличии атрибута name или id в документ добавляются элементы сле- дующих типов: Form, img и Applet. Кроме того, все элементы с атрибутом id за исключением элементов ввода в форме добавляются прямо в окно, что позволяет обращаться к ним без использования семейства all документа: <Н1 ID="myHl">Welcome to Му Page</Hl> <FORM ID="form 1"> CINPUT TYPE=TEXT ID="textl"> </FORM> CSCRIPT LANGUAGE="JavaScript”> // Доступ к myHl как свойству окна. alert(myHl.id); // Вывод id. // Доступ к myHl посредством семейства all. alert(document.all.myHl.id); // Элементы ввода в форме доступны посредством формы. alert(forml.textl.id); </SCRIPT> Встроенные семейства Документ содержит ряд стандартных семейств, которые подчиняются прин- ципам, изложенным в начале этой главы. Данные семейства поставляются для совместимости с более ранними версиями браузеров. В табл. 7.1 пере- числены семейства и теги элементов, которые содержатся в них. Таблица 7.1. Семейства и теги их элементов Семейство Теги Описание all Все теги Все элементы в документе, в исходном порядке anchors <A NAME...=> Закладки applets <APPLET>; <OBJECT> Внедренные объекты и апплеты Java forms <FORM> Формы frames <IFRAME> Встроенные фреймы images <IMG> Изображения links <A HREF=...>; <AREA> Ссылки. Если элемент Anchor содержит атри- буты name и HREF, то он будет представлен в семействах links и anchors scripts <SCRIPT> Сценарии
192 Часть И. Структура документа Вместо расширения данного списка произвольными тегами, семейства представляют метод tags для создания нового семейства, элементы которого выбраны по определенному тегу. Метод tags исключает необходимость смешения объектной модели с семейством для каждого типа элемента и по- зволяет разработчику определять интересующие его элементы. Метод tags Кроме метода item, все семейства элементов документа представляют метод tags. Метод tags использует параметр, представляющий тег как строку и возвращает семейство всех элементов с данным тегом, как показано в при- веденном ниже коде: <HTML> <BODY> <Н1>Му Header</Hl> <P>This is <STRONG>strong tcxt</STRONG> and more <STRONG>strong</STRONG> text.</P> <Hl>Another Header 1</H1> </BODY> </HTML> Приведенные ниже выражения используют метод tags для создания се- мейств элементов из предыдущего кода: document.all.tags("Hl") // Семейство всех элементов Hl document.all.tags("STRONG") // Семейство всех элементов Strong document.all.tags("STRONG")[0] // Первый элемент Strong document.all.tags("P").length // 1 В отличие от метода item метод tags всегда возвращает семейство, даже если на странице находится только один элемент. Например, вызов метода tags в элементе Body будет возвращать семейство, даже если существует только один элемент Body: document.all.tags("Body") // Семейство с одним элементом Body document.all.tags("Body")[0] // Первый элемент в семействе Метод tags всегда возвращает семейство, поскольку он был разработан с одной целью — для отбора элементов из семейства и создания сокращен- ного семейства. Метод item возвращает одиночный элемент, который совпа- дает с идентификатором. Там, где обнаруживаются дублирующиеся элемен- ты, метод возвращает семейство, а не ошибку. Пустые семейства Если метод tags вызывается для тега, который отсутствует в документе, то будет возвращено пустое семейство с нулевыми элементами:
Глава 7. Семейства элементов документа 193 if (0 = document.all.tags("Hl").length) alert("There are no Hl elements in this document.”); Чтобы обеспечить возможность запроса и отбора неизвестных элементов, метод tags не возвращает ошибку, когда анализирует недействительный тег. Индивидуальные семейства Большинство встроенных семейств документа совпадают с семействами, ко- торые можно создать, используя метод tags на основе семейства all. На- пример, семейство forms совпадает с семейством, созданным при вызове метода tags с параметром form. Приведенный ниже код создаст семейство, эквивалентное семейству forms: document.myforms - document.all.tags("form"); Можно создать индивидуальные семейства и добавить их в объект document, используя аналогичный метод, как показано в следующем примере: // Создание семейства tables в документе, document.tables - document.all.tags("TABLE"); Данный метод использует элемент, поддерживаемый JavaScript, так что дан- ный код не может быть запущен в VBScript и возможно не будет работать в других языках. В VBScript необходимо создать переменную для хранения семейства. В приведенном выше коде продемонстрировано, что многочисленные се- мейства часто ссылаются на одинаковый набор элементов. Поэтому ссылка на элемент в любом семействе представляет собой то же самое, что и ссылка на элемент в семействе all. Например, приведенный ниже фрагмент кода возвращает значение true, поскольку на один объект была установлена ссылка из двух различных семейств: // Оба выражения указывают на один объект. document.forms[0] == document.all.tags("FORM")[0]; Семейство all в документе с набором фреймов Документ, который содержит набор фреймов, также поддерживает объект document и представляет то же семейство all. Элемент Frameset заменяет элемент Body в семействе all, поскольку документ может содержать традиционное содержание тела документа (body) или набора документов (frameset). Все элементы Frameset и Frame в доклеите приведены в порядке исходного кода, что полезно для определения расположения фреймов на экране:
194 Часть II. Структура документа <HTML> <HEAD> <TITLE> Демонстрация набора фреймов </TITLE> </HEAD> <FRAMESET ROWS="60, *"> <FRAME SRO"a.htm"> <FRAME SRC="b.htm”> </FRAMESET> </HTML> Семейство all для данного документа содержит элементы в следующем по- рядке: HTML, Head, Title, Frameset, Frame, Frame. Кроме того, все атрибуты элементов Frameset и Frame представлены посред- ством семейства all. Большей части атрибутов могут быть присвоены новые значения, но в некоторых случаях значения атрибутов не пересчитываются. Например, когда граница набора фреймов не может быть изменена после воспроизведения набора фреймов на экране. Однако набор фреймов будет корректно обновляться, если изменить значения его атрибутов row и col, или значения атрибутов src или name одного из фреймов. Семейства в документах с набором фреймов отличаются от семейств в дру- гих документах по отношению к включению нераспознаваемых элементов. В объектной модели представлены только те нераспознаваемые элементы, которые появляются перед первым тегом <frameset>. При обнаружении тега <FRAMESET> все Элементы, которые отличаются ОТ Frameset И f rame, игнори- руются и не учитываются в объектной модели. Игнорируются даже элемен- ты NoFrames. Если элемент NoFrames находится Перед элементом Frameset, то он представлен в семействе all, но содержание данного элемента является недоступным. Данное ограничение может быть снято в будущей версии Internet Explorer. Структура и семейства HTML В этом разделе внимание сосредоточено на образовании семейств документа во время анализа документа. Предполагается, что HTML-документы удовле- творяют правилам, установленным в определении типа документа (document type definition, DTD) HTML. Объектная модель HTML основана на этих правилах с учетом некоторых исключений, гарантирующих корректность построения структуры документа. Далее вводятся взаимоотношения между DTD и семействами, представленными в документе. Построение семейства all Семейство all непосредственно соотносится с деревом HTML-документа. Приведенный ниже HTML-документ демонстрирует данное отношение:
Глава 7. Семейства элементов документа 195 <HTML> <HEAD> <TITLE> Мой документ </TITLE> </HEAD> <BODY> <Hl>Welcome to My Page</Hl> <P>This is an <STRONG>important document.</STRONG></P> </BODY> </HTML> На рис. 7.1 показаны связи между элементами в данном документе. Рис. 7.1. Взаимосвязи между элементами в HTML-документе Семейство документа all, которое содержит все элементы документа, пред- ставляет данное дерево. Семейство содержит элементы дерева в том поряд- ке, в котором они встречаются в исходном коде. Анализатор создает семей- ство all, выполняя операцию, которая известна как прямое прослеживание (preorder traversal) дерева. Содержание и порядок элементов в семействе all в исходном состоянии в данном примере перечислены ниже: html, Head, Title, Body, Hl, Paragraph, Strong. Семейство ail всегда представляет текущее состояние документа. Можно изменить элементы в семействе all путем манипулирования динамическим содержанием, но семейство ail всегда поддерживает порядок элементов, даже когда сценарии изменяют содержание. Манипулирование динамиче- ским содержанием подробно обсуждается в главе 13. Область действия Дерево HTML содержит информацию, которую трудно получить в семействе ан. А именно, область действия (scope) каждого элемента. Область действия элемента представляет собой набор содержащихся в нем элементов. Напри- мер, в предыдущем документе элемент Paragraph содержит элемент strong, так что элемент strong находится внутри области действия элемента Paragraph. Вы можете определить область действия элемента путем анализа
196 Часть II. Структура документа свойств parentEiement и children каждого элемента в семействе all. Эта процедура описана в главе 8. ( Примечание Семейство all, так же квк и все семейства элементов, представляет элемент как одиночный объект. Элементы, а не индивидуальные открывающие и закры- вающие теги, необходимы для манипулирования структурой документа По- скольку представлены элементы, а не индивидуальные теги, то легче понимать и работать с семействами. Исключением из данного правила являются нерас- познаваемые теги. В данном случае, любой нераспознаваемый тег, независимо от того, является тег открывающим или закрывающим, добавляется в семейст- во. Нераспознаваемые теги не имеют области действия и дочерних элементов Данное ограничение очень подробно обсуждается ниже в разделе "Нераспознаваемые элементы" данной главы. Неявные элементы DTD для HTML определяет, что теги для элементов html, Head, Body и TBody являются необязательными в HTML-документе, поскольку данные элементы могут быть выведены из контекста документа, как показано в примере ниже: <TITLE> Добро пожаловать в Мой документ </TITLE> <Hl>Welcome to Му Page</Hl> <P>This is an <STRONG>important document.</STRONG></?> Данный документ эквивалентен предшествующему документу. Деревья, и поэтому содержание семейств all, совпадают. Семейство all всегда пред- ставляет элементы html, Head и Body для каждого документа, независимо от того, указаны они явно или нет. Разделение между Head и Body В документе без тегов <неаг» и <body> разделение между заголовком и телом документа определяется правилами HTML, как указано в DTD. Элемеш Head содержит определенный набор элементов, которые отличаются от на- бора в элементе Body. Поэтому после обнаружения первого элемента Body (папример, HI) область действия автоматически изменяется с заголовка на тело. Приведенный ниже фрагмент кода представляет DTD для заголовка доку- мента. Проверив данное DTD, можно более ясно проследить отличие между заголовком и телом документа: <!ENTITY % head.misc "SCRIPT|STYLE|META|LINK" — повторяемые элементы заголовка —> <!ENTITY % head.content "TITLE S ISINDEX? & BASE?”> <!ELEMENT HEAD О О (%head.content) +(%head.misc)>
Гпава 7. Семейства элементов документа 197 Данный код показывает, что может быть не более одного элемента isindex и один элемент вазе, что должен быть один элемент Title и любое число элементов, определенных компонентом head.misc. С учетом двух исключе- ний, элементов style и Script, наборы компонентов, доступных в заголовке и теле документа, различны. Поэтому анализатору легко определить, когда область действия переключается от заголовка к телу. Элементы style и Script неоднозначны, поскольку они существуют в заго- ловке и теле. Если элементы style или script обнаруживаются в документе до раздела тела, то элемент считается содержанием заголовка. Данное пра- вило не влияет па воспроизведение или поведение документа, но его важно понимать, поскольку оно определяет область действия элементов Head и Body. Необязательные завершающие теги Для некоторых элементов в HTML не требуются закрывающие теги. Напри- мер, тег <р> не требует наличия завершающего тега </р> для обозначения его области действия. Для определения завершения параграфа (Paragraph) или других элементов используется определение DTD. Когда встречается элемент, который не может находиться в данной области, то его область действия считается завершенной. Как показано в следующем примере, если после тега <р> следует тег <Н2>, то элемент Paragraph заканчивается на теге <Н2>, поскольку элемент Н2 нс может быть дочерним элементом элемента Paragraph. <HTML> <Hl>Scott's Home Page</Hl> <P>Welcome to my page.<H2>New Cool Stuff</H2> </HTML> Дерево на рис. 7.2 представляет документ HTML. Обратите внимание, что элемент н2 является дочерним элементом Body, а не элемента Paragraph. Рис. 7.2. Диаграмма дерева документа с неявными тегами завершения В целом документы легче читать и обновлять, когда явно указаны закры- вающие теги. В отсутствие закрывающих тегов пользователь, который про-
198 Часть II. Структура документа сматривает исходный код документа, должен знать определение типа доку- мента HTML, чтобы установить взаимоотношения между различными эле- ментами. Нераспознаваемые элементы Важность анализа нераспознаваемых элементов в HTML-документе увели- чивается по мере развития браузеров. Представьте себе введение тега <Н7>. Новые браузеры будут интерпретировать <Н7> как тег контейнера блока, но браузеры предыдущих версий не будут его распознавать. В сочетании с пра- вилами HTML теги начала и завершения <н7> игнорируются при воспроиз- ведении документа гипотетическим браузером низкого уровня, поскольку для нераспознаваемых тегов недоступна информация определения DTD для установки правил и области действия тега. Поскольку отсутствует определение типа документа (DTD) для нераспозна- ваемых элементов, то нераспознаваемые открывающие и закрывающие теги представлены в семействе all. В отличие от правил HTML, в которых уста- новлено, что нераспознаваемые элементы должны быть проигнорированы, обз>сктная модель включает нераспознаваемые теги для того, чтобы обеспе- чить разработчику полную информацию о документе. Представлен также нераспознаваемый закрывающий тег, поскольку отсутст- вует способ точного определения, является ли документ контейнером. Даже если открывающие и закрывающие теги появляются в документе последова- тельно, то нет гарантии, что их использование согласуется с правилом DTD, если оно существует для данного элемента. Например, элемент может быть не определен в DTD как элемент-контейнер. Поэтому оба нераспознавае- мых открывающих и закрывающих тега всегда представлены как конечные узлы (leaf nodes) в дереве: <нтмь> <P>Welcome to my <FOO><B>cool</B> document.</FOO></P> </HTML> Дерево на рис. 7.3 демонстрирует, как внутренний анализатор представляет данный документ с нераспознаваемыми элементами. Семейство all в предыдущем примере содержит следующие элементы: нтмг., Head, Body, Paragraph, <foo>, Bold, </foo>. Обратите внимание, что элемент Bold считается дочерним элементом элемента Paragraph, а не элемента гоо. Поскольку информация DTD об элементе Foo недоступна, то отсутствует способ надежного определения, является ли элемент Foo контейнером. Для нераспознаваемых элементов открывающие и з;Гкрывающие теги позволяют разработчику рассчитать область действия элемента путем просмотра семей- ства all вручную.
Гпава 7. Семейства элементов документа 199 с нераспознаваемыми тегами начала Рис. 7.4. Измененное и конца <гоо> дерево документа Если в будущей версии Internet Explorer элемент Foo станет действительным элементом HTML it сможет содержать текст, то изменится дерево докумен- та. Новое дерево показано на рис. 7.4. Порядок элементов будет согласован в различных реализациях, но число элементов и дерево документа могут сильно отличаться в зависимости от поддержки элемента Foo. Данное различие может привести к возникнове- нию проблем, если ваша программа учитывает порядковое положение эле- ментов в семействе, поскольку число представленных элементов может из- меняться от браузера к браузеру. Напротив, код, который обращается к оп- ределенному элементу, должен всегда использовать идентификатор id или идентифицировать элемент в более явном контексте. Все нераспознаваемые закрывающие теги также представлены в объектной модели, поскольку объектная модель не пытается связать недействительные открывающие и закрывающие теги и принимает их в семейство так, как они определены в документе. Поэтому если тег </bar> находится в середине до- кумента, то он будет представлен в семействе all, даже если отсутствует от- крывающий тег <BAR>. С точки зрения DTD все нераспознаваемые открывающие и закрывающие теги считаются не имеющими содержания. Вся информация об атрибутах и таблице стилей, обнаруженная для нераспознаваемого тега, не будет воздей- ствовать на режим воспроизведения документа, но будет представлена в объектной модели. Непарные закрывающие теги При обнаружении непарного закрывающего тега, который распознается анализатором, HTML устанавливает, что закрывающий тег должен игнори- роваться. Однако так же как и для нераспознаваемых тегов, непарные за-
200 Часть II. Структура документа крывающие теги представлены в семействе all. В приведенном ниже при- мере закрывающий тег </в> представлен в объектной модели: <HTML> This is not bold.</B> </HTML> Закрывающий тег представлен в модели, поскольку объектная модель пыта- ется поддерживать точное представление документа Перекрывающиеся элементы Перекрытие элементов возникает, когда в документе не поддерживается действительная иерархия контейнеров. Приведенный ниже пример показы- вает перекрытие элементов strong и ем: <html> <BODY> <P>This is a <STRONG>demonstration of <EM>overlapping</STRONG> elements. </EM>< ''?> </BODY> </HTML> Элементы перекрываются, по не влияют на расположение или порядок се- мейства all. Семейство all состоит из следующих элементов: нтмь, Head, Body, Paragraph, Strong, EM. Дерево дан- ного документа, показанное на рис. 7.5, нс показывает перекрытия элементов или реальную область действия каждого эле- мента. Рис. 7.5. Диаграмма дерева документа с перекрывающимися элементами Перекрывающиеся элементы, в действительности, являются некорректным HTML. Для установки необходимой модели поведения без использования перекрывающихся тегов следует создать документ с четкой иерархией кон- тейнеров: <HTML> <BODY>
Глава 7. Семейства элементов документа 201 <P>This is a <STRONG>demonstration of <EM>overlapping</EM></STRONGXEM> elements.</EM> </P> </BODY> </HTML> Перекрытие элементов имеет незначительное влияние на большинство се- мейств, но семейство элемента children может быть некорректным. Взаимоотношения между перекрывающимися элементами и содержанием документа являются строгими и обсуждаются в главе 13. Содержание без тегов Содержание без тегов — это текст, который не содержится ни в одном эле- менте. Такой текст часто появляется внутри тела документа: <HTML> <BODY> В данной строке отсутствуют теги. <Р> Данная строка находится в элементе Paragraph.</Р> Данная строка находится после элемента Paragraph и не содержит тегов. </BODY> </HTML> Семейство all этого HTML-документа будет содержать только элементы HTML, Head, Body И Paragraph. Отс/ГСТВуЮТ ЭЛеМСНТЫ, Которые Представляют текст за пределами контейнеров. В строгом HTML считается, что данный текст находится внутри элемента Paragraph. Однако тег <р> не может быть синтезирован в данном случае, поскольку явно определенные параграфы имеют несколько отличную схему воспроизведения. Недействительный HTML Динамический HTML разработан для работы с действительным HTML. По- этому теги, которые помещены за пределами их области действия, обычно обрабатываются как нераспознаваемые элементы. Данное правило не явля- ется зафиксированным, однако в некоторых случаях HTML может быть ис- правлен в ходе анализа документа. Например, в коде находится приведенное ниже неправильное определение таблицы: <нтмь> <BODY> <TD> Ячейка таблицы за пределами таблицы.</TD> </BODY> </HTML>
202 Часть II. Структура документа В данном документе ячейка таблицы появляется в области, к которой она не принадлежит, — за пределами таблицы. Во время обработки документа ячейка таблицы не распознается и обрабатывается как нераспознаваемый элемент. Поэтому открывающие и закрывающие теги считаются анализато- ром недействительным. Семейство all представляет элементы данного до- кумента HTML в следующем порядке: HTML, Head, Body, <TD>, </td>. He следует писать документы, полагаясь на данное поведение. Браузеры могут исправить код HTML или не вносить никаких изменений и проигно- рировать неправильно помещенные элементы. Единственной гарантией то- го, что семейство элементов построено согласованно, является создание действительных элементов HTML. Существует несколько известных исключений, для которых дерево докумен- та не будет соответствовать определению типа документа HTML. Данные исключения существуют, поскольку они появляются в большом числе доку- ментов в Internet. Здесь обсуждаются далеко не все исключения, но они час- то встречаются в HTML-документах. Списки Списки являются одной из нескольких областей, в которой код HTML не исправляется анализатором. Для обеспечения совместимости объектная мо- дель принимает два случая недействительного кода HTML в качестве дейст- вительной разметки: □ Элементы ы могут находиться за пределами контейнеров списков иь и оь. □ Контейнер списка может прямо содержать другие контейнеры списка. Первое исключение было разрешено в Netscape Navigator 2.0 дяя создания маркированных списков без отступа. Второе исключение возникло вследст- вие общей некорректной практики создания вложенных списков. При обнаружении первого исключения Netscape Navigator 2.0, реализация которого была поддержана в Internet Explorer 3.0, воспроизводит элемент списка без отступа. Хотя определения типа документа для элементов ы за- прещают их существование за пределами списков, определение DTD. кото- рое используется для создания показанного в следующем коде дерева, явля- ется неопределенным и не осуществляет автоматический переход на новую строку элементов ы. <HTML> <BODY> <Ы> Данный элемент LI находится за пределами списка.</LI> </BODY> </HTML>
Гпава 7. Семейства элементов документа 203 Элементы в семействе all данного документа располагаются в следующем порядке: HTML, Head, Body, LI. Второе исключение, в котором вложенные списки используются целиком для увеличения отступа маркера списка, продемонстрировано ниже: <HTML> <BODY> <UL> <UL> <LI> Элемент маркированного списка с большим отступом. </Ы> </UL> </UL> </BODY> </HTML> Этот код HTML нарушает правила DTD, поскольку элементы ul могут со- держать только элементы ы, а не другие элементы ul. При обнаружении данной ситуации исправление кода не производится. Порядок элементов в семействе ail для данного документа таков: html. Head, Body, ul, ul, li. Элементы форм в таблицах Также общепринято использовать формы в таблицах (за пределами ячеек) для создания формы, которая охватывает многочисленные строки или ячей- ки, как показано ниже: <HTML> ' <HEAD> <TITLE> Формы в таблицах </TITLE> </HEAD> <BODY> <TABLE> <FORM NAME="Forml"> <TRXTD>Forml-related fie.lds</TDX/TR> <TRxTD>More Forml-related fields</TDx/TR> </FORM> <FORM NAME="Form2"> <TRXTD>Form2-related fields</TDX/TR> </FORM> </TABLE> </BODY> </HTML> В этом документе формы будут поддерживаться с корректной областью дей- ствия внутри таблицы.
204 Часть II. Структура документа Дерево для данного документа представлено на рис. 7.6. Рис. 7.6. Диаграмма дерева для документа с элементами Form внутри элемента Table Возможно, существуют другие исключения из определения DTD. В целом, недействительный HTML может привести к созданию непредсказуемого де- рева, которое может быть несогласованным в различных версиях браузеров. Поэтому следует писать код HTML, который соответствует DTD. Это по- зволяет не только сделать объектную модель более согласованной, но также повышает вероятность того, что различные браузеры будут воспроизводить документ одинаково.
Глава 8 Сценарии и элементы В данной главе показано, как программировать элементы HTML-документа и манипулировать ими. Все элементы совместно используют общий набор данных для идентификации элемента, доступа к его атрибутам и определе- ния взаимоотношений между элементами в документе. Кроме того, многие элементы обеспечивают индивидуальные свойства, методы и события, что повышает возможности управления документами. Примеры элементов обсуждаются в главах 9 и 10. Рассмотрены следующие темы: □ Идентификация элементов. В данном разделе показано, как различать элементы в документе. HTML предоставляет набор атрибутов, полезных для идентификации и группирования элементов, включая имя тега и ат- рибуты ID, CLASS И NAME. □ Доступ к атрибутам элемента. Все объекты элемента инкапсулируют ин- формацию о своих атрибутах и даже предоставляют доступ к недействи- тельным атрибутам н значениям, которые могут быть определены для элемента. В этом разделе показано, как обращаться и использован, дан- ную информацию. □ Информация анализа. В главе 7 описана процедура создания семейства ап документа и получения доступа к нему. Семейство ап предоставляет доступ к отдельным элементам, а каждый элемент представляет свои взаимоотношения с другими элементами, включая информацию об ана- лизе и воспроизведении документа. Информация анализа представляет основной источник HTML, а информация воспроизведения - информа- цию, которая была определена в ходе создания документа. Данный раз- дел рассматривает взаимоотношения межд/элементами в дереве анализа и показывает, как эти взаимоотношения представляются отдельными элементами.
206 Часть II. Структура документа □ Создание новых элементов. Данный раздел показывает, как можно доба- вить элементы в документ, используя метод createElement. Существует два метода управления структурой документа: • Создание элементов в памяти. • Прямое изменение содержания HTML. Динамический HTML в настоящее время позволяет создавать в памяти только некоторые элементы. □ Настройка элементов. В разделе продемонстрированы методы настройки существующих элементов и создания новых элементов, определенных пользователем. Настройка сходна с выделением подкласса элемента и использует способность динамического HTML представлять нераспозна- ваемые атрибуты для языка написания сценариев. Элементы могут также быть определены путем использования нераспознаваемых элементов в объектной модели. Определенные пользователем элементы могут содер- жать дополнительную метаинформацию о документе, доступ к которой и ее использование можно осуществлять посредством объектной модели. Идентификация элементов При написании сценариев и таблиц стилей можно применить написанный код к одному определенному элементу, ко всем элементам одного типа или к смешанному набору элементов. Объекты элементов имени несколько свойств, которые упрощают их идентификацию перечисленными выше спо- собами. Свойства id и className объекта содержат значения соответствую- щих атрибутов id и class элемента, а его свойство tagName содержит имя тега элемента. Код может использовать свойство id для создания ссылки на одиночный элемент, свойство tagName — для ссылки па все элементы дан- ного типа и свойство className — для ссылки на указанные элементы. Элементы, которые имеют атрибут name, также имеют свойство паше, кото- рое содержит значение атрибута. Вы можете использовать в программе свойство name для идентификации одиночного элемента пли группы связан- ных элементов (таких как кнопки переключатели). Но свойство name нс так широко используется как свойство id и объектная модель включает его пре- имущественно для обеспечения обратной совместимости. Значения свойства tagName набраны символами в верхнем регистре. Свойст- ва id, name и className являются чувствительными к регистру. Значение coolstuff, например, представляет класс, отличный от значения cooistuff в чувствительном к регистру языке, типа JavaScript. Таблицы стилей, однако, связаны с элементами независимо от регистра. В табл. 8.1 суммирована информация о четырех свойствах, которые иденти- фицируют элементы.
Глава 8. Сценарии и элементы 207 Таблица 8.1. Свойства, идентифицирующие элементы Атрибут Свойство Является ли чувствитель- ным к регистру? Элементы, к которым применяется (Ничего) tagName Всегда в верхнем регистре Все, включая примечания ID id Да Все, за исключением приме- чаний CLASS className Да Все, за исключением приме- чаний NAME name Да Anchor, Applet, Button, Form, IMG, Input, Map, Meta, Object, Select и TextArea Используя свойства для идентификации элементов, можно написать сцена- рий, который будет выполнять аналогичные действия для всех элементов, в любом выбранном наборе элементов. Обработчик события нажатия кнопки в приведенном ниже примере реагирует по-разному на нажатие кнопки мыши на элементе со значением id равным fi23, элементах класса coolstuff и элементах Н1. В любом случае обработчик изменяет внутренний стиль элемента, чтобы изменить его отображение. <нтмь> <HEAD> <TITLE>Identifying Elements</TITLE> <SCRIPT FOR="document" EVENT=”onclick()” LANGUAGE=”JavaScript"> // Событие нажатия генерируется в документе независимо от места // нажатия кнопки. // Свойство стиля дает доступ к внутреннему стилю, var curElement = event.srcElement; if ("1'123" ~= curElement.id.toUpperCase()) ( // Toggle element color between red and blue. if ("red" == curElement.style.color) curElement.style.color = "blue"; else curElement.style.color = "red"; } if ("COOLSTUFF" == curElement.className.toUpperCase()) ( //Увеличивает или уменьшает размер шрифта при нажатии // кнопки мыши, if == curElement. style, fontsize) curElement. style, fontsize = ”1,50%"; else curElement.style.fontsize =
гов Часть II. Структура документа if ("Hl" == curElement.tagName) ( // Переключает режимы отображения заголовка: выровненный //по центру или по левому краю. if ("center" -- curElement.align) curElement. align = else curElement.align = "center"; J </SCRIPT> </HEAD> <BODY> <P ID="fl23" STYLE="color:red"> Данный параграф имеет уникальный номер ID.</P> <Hl>Clicking on an Hl element changes its alignment.</Hl> <P>This paragraph contains <STRONG CLASS="coolstuff">cool stuff.</STRONG> </P> <H1 CLASS="coolstuff"> Данный заголовок также принадлежит классу cool stuff. </Н1> </BODY> </HTML> В приведенном выше коде значения className и id преобразуются в верх- ний регистр перед проведением сравнений. Таким образом, данные значе- ния обрабатываются без учета регистра. Доступ к атрибутам элемента Каждый объект элемента представляет его трибуты, стиль и содержание для языков написания сценариев. Данная информация доступна из исход- ного кода документа. В этом разделе будет показано, как используются ат- рибуты. В главе // обсуждается доступ к стилю элемента, а глава 13 содержат обсуждение доступа к содержанию элемента. Типы данных В HTML атрибут всегда использует один из следующих типов данных: число (number), строка (string), строка из стандартного списка (string from prede- fined list) или логическое значение (compact value). (Логические значения со- держат значения true (истина) или false (ложь)). Определение типа доку- мента (DTD) устанавливает тип данных для каждого атрибута.
Глава 8. Сценарии и элементы 209 В объектной модели динамического HTML каждый атрибут представлен как свойство, принадлежащее к одному из четырех перечисленных ниже типов данных: □ 32-разрядное целое для числовых значений □ Логическое значение □ Строка для произвольных или определенных строк □ Указатель функции для атрибутов событий Сценарий в приведенном ниже HTML-документе использует все четыре ти- па данных: CHTML» <HEAD» <TITLE» Программирование атрибутов — типы данных </TlTLE> </HEAD> <BODY> <INPUT TYPE=TEXT SIZE=35 ID="txtl" DISABLED» <H1 ALIGN=”Left" ID="hdl" ONCLlCK-"alert('Clicked!’)> Это выровненный по левому краю заголовок. </Н1» <SCRIPT LANGUAGE»"JavaScript”» alert(document.all.txtl.disabled); // Логическое значение true // (истина) alert(document.all.hdl.align); // Значение String // (строка) alert(document.all.txtl.size); // 32-разрядное целое, // равное 35 alert(document.all.hdl.onclick); if Указатель функции </SCRIPT» </BODY» </HTML» Свойство представлено для каждого определенного атрибута в HTML, даже если атрибут не явно определен в документе. Например, элемент input в предыдущем коде нс имеет определенного значения value, но в объектной модели все элементы input всегда представляют свойство value. Значение свойства, которое соответствует неопределенному атрибуту, зависит от его типа данных. Свойства строк содержат пустые строки. Свойства числовых значений содержат значения по умолчанию для соответствующих атрибутов. Логические свойства содержат false. Указатели функций содержат null. Атрибут свойства содержит код, который выполняется в результате опреде- ленного действия. При анализе строки кода создается объект function. Свойство, представляющее подобное событие, содержит нс определение функции, а указатель на функцию.
210 Часть II. Структура документа Если назначить значение одного типа данных свойству с другим типом дан- ных, то результат будет различен в разных языках написания сценариев. Значение будет приведено к типу данных свойства или возникнет ошибка. Например, если вы назначаете число строковому свойству в JavaScript, то транслятор преобразует число в строку до проведения назначения. Если . язык поддерживает явный переход от одною тина к другому, то вы должны явно согласовать значения для получения предсказуемых результатов. Функция parseint в JavaScript, например, изменяет строковое представление числа на действительное число: document.myText.size « parseint("ЮО"); // 100 Соглашения об именовании Язык HTML позволяет определять атрибуты независимо от регистра, а JavaScript является чувствительным к регистру. Для упрощения программи- рования в чувствительных к регистру языках объектная модель представляет вес свойства, используя соглашение об именовании (naming convention), кото- рое позволяет определять имя свойства для любых существующих атрибутов без необходимости поиска их в документации. По соглашению об именовании имена всех свойств начинаются с символа в нижнем регистре. Присоединенные ключевые слова начинаются с пропис- ной буквы. Например, tagName. Поскольку большинство атрибутов состоит из одиночного ключевого слова, то имена соответствующих свойств записа- ны в основном в нижнем регистре. Для каждого атрибута соответствующее свойство имеет имя, совпадающее с названием атрибута, за исключением двух случаев: свойство className пред- ставляет атрибут class, а свойство htmiFor представляет свойство fob (ис- пользуемое с элементами Label и Script). Данные исключения необходи- мы, поскольку ключевые слова for и class зарезервированы во многих язы- ках программирования. Доступ к исходным значениям Поскольку HTML основан на тексте, то возможны случаи, когда атрибут может содержать значение, которое не совместимо с типом данных пред- ставленного свойства. Например, атрибут sm: представляет целое значение текстового окна. Однако если исходный код HTML содержит строку, а не число, то свойство size, тем не менее, возвращает размер но умолчанию, поскольку тип данных для значения является заданным. Объектная модель динамического HTML гарантирует, что даже к недействительным атрибутам и значениям можно получить доступ при помощи сценариев. Все элементы используют приведенные ниже методы доступа к неизменному значению в исходном документе.
Гпава 8. Сценарии и элементы 211 □ getAttribute(propertyName [, options)) □ setAttribute(propertyName, Value [, options]) □ removeAttribute(propertyName (, options)) Метод getAttribute использует имя свойства как строку и возвращает зна- чение, которое находится в исходном коде. Например, если исходный файл устанавливает атрибут size равным строке big, то свойство size возвращает размер по умолчанию, равный 20. Но getAttribute ("size") возвращает строку big, поскольку метод getAttribute всегда возвращает неизменное значение из исходного кода. Метод setAttribute позволяет разработчику управлять обратной операцией, таким образом строка может быть вставлена в поток HTML, даже если зна- чение свойства является числом. Например, setAttribute("size", "small”) помещает строковое значение small в атрибут size. Свойство элемента size по-прежнему возвращает значение 20. Метод removeAttribute используется для удаления атрибута из объекта. Эти три метода представляют параметр options, который управляет просмотром. В настоящее время параметр управляет только чувствительно- стью к регистру. По умолчанию значение параметра options равно false, поэтому просмотр является нечувствительным к регистру. Если значение options равно true, то просмотр является чувствительным к регистру, ис- пользуя внутреннее выделение прописными буквами известных атрибутов и выделение прописными буквами нераспознаваемых атрибутов в исходном коде. В целом чувствительность к регистру не обязательна и методы атрибутов могут быть вызваны без необязательного флага. Главным назначением пара- метра options является обнаружение свойств при наличии нескольких свойств с одинаковыми именами, символы в которых находятся в различ- ных регистрах. Без использования параметра options возвращается первое в списке свойство с совпавшим именем. Примечание Несмотря на то, что разработчики объектной модели постарались избежать совпадений с общепринятыми зарезервированными словами, возможны слу- чаи, когда название атрибута будет совладать с зарезервированным словом в языке программирования. В этом случае могут быть использованы три метода атрибутов для доступа к значению свойства определенного элемента вместо прямого обращения к атрибуту. Перечислимые типы данных Многие другие объектные модели представляют списки значений как лере-' числимые типы данных. Обычно перечислимый тип данных является цело- численным или другим значением, н определено множество копстаит для
212 Часть II. Структура документа представления его разрешенных значений. Для гарантии языковой ней- тральности в объектной модели динамического HTML не используется пе- речисление для целых значений. Напротив, все списки значений представ- лены как строковые значения. Например, атрибут align сохраняет строку, которая, как предполагается, является одним из трех строковых значений: left, right И center. Атрибуту может быть назначена строка, регистр символов которой не имеет значения, и она будет правильно учтена. Например, значение атрибута align в HTML или соответствующего свойства align может быть равно le ft или LeFT, или любой другой комбинации строчных и прописных букв. Однако при извлечении значение всегда возвращается в нижнем регистре. Перечислимые строковые значения преобразуются в нижний регистр во время анализа или назначения. Исходный регистр данных значений недос- тупен. Методы gelAttribute, setAttribute И removeAttributc не учитывают исходный регистр символов перечислимых строк и возвращают их в нижнем регистре. Нераспознаваемые атрибуты Обработка нераспознаваемых элементов в объектной модели была описана в главе 7. Динамический HTML корректно представляет нераспознаваемые атрибуты в любом элементе при помощи методов атрибутов. Используя эти методы, нераспознаваемые атрибуты можно добавить в любой элемент или удалить из него. В JavaScript данный подход получил дальнейшее разви- тие — все нераспознаваемые атрибуты могут быть также представлены в ка- честве свойства элемента, как показано ниже: <Н1 ID=myHl badAttribute=Test> JavaScript обеспечивает доступ к свойству, названному badAttribute так же, как и к другим свойствам элемента: alert(document.all.myHl.badAttribule) // Тест alert(document.all.myHl.getAttribute("badAttribute")) // Тест Нераспознаваемые атрибуты представлены как свойства в том же регистре, в котором они находились в исходном документе. Для нераспознаваемых атри- бутов выделение прописных букв в атрибуте документа не имеет связи с реги- стром атрибута в объектной модели. Для выполнения нечувствительных к ре- гистру просмотров должны быть использованы методы атрибутов. Это также исключает возможность возникновения проблем, вызванных типографиче- скими ошибками при выделении прописных букв*в именах атрибутов Ниже, в разделе данной главы “Настройка существующих элементов" демонстрируют- ся более изощренные методы использования нераспознаваемых атрибутов.
Гпава 8. Сценарии и элементы 213 Информация анализа Каждый элемент представляет информацию о себе и своих связях с другими элементами. Представленная информация может быть разделена на две ка- тегории: информация анализа и информация воспроизведения. Информация анализа непосредственно связана с атрибутами, стилями и содержанием, которое определяется документом. Информация воспроизведения представ- ляет собой параметры, вычисленные браузером перед отображением элемента. Информация анализа (parsing information) включает в себя рассмотренную ранее идентификацию свойств, все известные и неизвестные HTML-атри- буты, таблицу внутренних стилей и взаимоотношения элементов с другими элементами в соответствии с определением DTD. Таблица внутренних сти- лей представляет информацию анализа, а не информацию воспроизведения, поскольку она явно определена в источнике документа, а не рассчитана во время воспроизведения. Информация воспроизведения (rendering information) представляет собой ин- формацию, которая рассчитывается браузером в ходе формирования доку- мента. Информация воспроизведения включает координаты и размер эле- мента относительно контекста воспроизведения. Контексты воспроизведения и результирующее дерево воспроизведения подробно обсуж- даются в главе 12. В остальной части данной главы рассматривается доступ к дереву анализа и его использование. Определение иерархии контейнеров HTML Есть несколько методов определения элементов, которые находятся внутри других элементов. Как упоминалось выше, родительский элемент может быть определен с помощью свойства parentElement. Дочерние элементы, которые находятся внутри элемента, перечислены в семействах элемента children и all. Семейство children представляет прямые дочерние элемен- ты, а в семействе all перечислены все элементы. Доступ к дочерним элементам Семейство all документа представляет все элементы HTML, которые нахо- дятся внутри документа. Данная концепция иерархии контейнеров выпол- няется для каждого объекта элемента. Каждый обз>ект элемента также пред- ставляет семейство all, которое содержит все элементы, находящиеся внут- ри данного элемента. Кроме того, семейство children представляет элементы, которые являются прямыми потомками текущего элемента. Дан- ные семейства работают в соответствии с теми же принципами, что и се- мейства элементов документа, введенные в главе 7. Используя данные се- мейства, можно создать совершенно самостоятельные элементы. Ниже при- ведено несколько примеров:
214 Часть II. Структура документа // Все элементы Н1 являются дочерними элементами тела документа document.body.children.tags("Hl") // Все элементы LI в третьем элементе UL на странице document.all.tags("UL")[2].children.tags("LI”) // Все элементы Paragraph, которые находятся внутри первого элемента D1V // и во вложенных элементах DIV или Table document.all.tags("DIV")(Of.all.tags("P") Проверка вложенности элементов Как упоминалось в главе 3, при помощи метода contains можно быстро оп- ределить, находится ли один элемент внутри области действия другого эле- мента. Метод contains принимает имя элемента и возвращает значение true, если данный элемент является дочерним элементом, дочерним элементом дочернего элемента и так далее. Метод contains был введен, чтобы упростить написание обработчиков собы- тий onmouseover и onmouseout. В главе 3 был приведен пример использова- ния метода contains для проверки того, что указатель мыши был перемещен относительно элемента, на котором возникло событие, а нс относительно просто дочернего элемента. Свойство sourceindex Все элементы представляют 32-разрядное целое свойство sourceindex, кото- рое содержит порядковое положение элемента в семействе ли документа только для чтения. Оно же определяет положение элемента в дереве анали- за, если дерево было преобразовано в список. Свойство sourceindex может быть использовано для определения относительного положения элемента и его связей с другими элементами в документе. Не следует чрезмерно полагаться на свойство sourceindex. Значения индек- сов могут измениться, если в будущем для документа будет создано большее количество элементов. Например, не следует ожидать, что значения sourceindex двух элементов будут всегда иметь фиксированные значения. Если вы используете свойство sourceindex, то проведите сравнения пуз ем помещения элемента в цикл. Создание дерева анализа Один из самых эффективных способов понимания отношений вложенности между контейнерами в HTML-документе заключается в создании дерева анализа с использованием семейства all документа. Приведенный ниже до- кумент содержит код, который автоматически выводит вложенную таблицу, представляющую иерархию контейнеров всех элементов в документе. Дан-
Гпава в. Сценарии и элементы 215 ный фрагмент кода может быть помещен в любой документ для быстрого получения изображения дерева. <HTML> <HEAD> <TITLE> Построитель дерева </TITLE> <SCRIPT LANGUAGE="JavaScript"> function buildTreeO ( var int Pa rents •= 0; var intlndent ~ 0; // strStruct сохраняет строку HTML, которая будет // представлять документ. var strStruct = "<HTMLxTITLE>Document Tree</TITLE>" + ”<BODYXTABLE BORDER CELLPADDING=5XTR>"; var elParent; // Просмотр всех элементов в документе. for (var intLoop = 0; intLoop < document.all.length; intLoop++) { elParent = document.all[intLoop]; // Определения глубины вложенности элемента. while (elParent.tagName != "HTML") { intParents++; elParent = elParent.parentElement; } // Установка вложения или прекращение вложения элементов // на основе нового значения глубины вложенности. if (intParents > intlndent) strStruct += "STABLE BORDER WIDTH=100% CELLPADDING=5><TR>"; else if (intParents < intlndent) { for (var intClose = intParents; intClose < intlndent; intClose++) strStruct += "</TABLE>”; } intlndent = intParents; intParents = 0; strStruct += ”<TD>" + document.all[intLoop].tagName; } // Закрытие всех оставшихся областей действия. for (var intClose = intParents; intClose < intlndent; intClose++) strStruct += "</TDX/TRX/TAB4.E>"; strStruct += "</BODYx/HTML>”; // Вывод нового документа в новом окне, var w = window.open!"", "tree");
216 Часть II. Структура документа w.document.open(); w.document.write(strStruct); «.document.closet) ; } window.onload = buildTree; </SCRIPT> </HEAD> <BODY> <Hl>Tree Builder</Hl> <UL> <LI>Test Item 1 <UL> <LI>Subitem 1 <LI>Subitem 2 </UL> </LI> <LI>Test Item 2</LI> </UL> <DIV> <P>This is <EM>cool. </EMX/P> ‘ </DIV> </BODY> </HTML> Данный код создает дерево путем перечисления семейства ап документа и расчета глубины вложения всех элементов с помощью свойства parcntElement. Данная процедура может быть переписана рекурсивно с помощью семейства children для каждого элемента. Рис. 8.1. Иерархия контейнеров HTML-документа
Глава 8. Сценарии и элементы 217 На рис. 8.1 показана иерархия контейнеров, сгенерированная данным ко- дом. Вложенные таблицы показывают область действия элементов относи- тельно других элементов. Свойство document Каждый элемент использует свойство document, представляющее документ, которому принадлежит элемент. Данное свойство позволяет общим сцена- риям определять документ, а в документе — окно, которое является исход- ным для произвольного элемента. Например, приведенное ниже выражение ссылается на окно, содержащее элемент: myElement,document.parentwindow // Окно для элемента. Создание новых элементов В документ можно добавлять элементы, используя один из двух методов: создавая новый элемент в памяти и связывая его с документом или прямо изменяя основное содержание HTML. Прямое изменение основного содержания HTML обсуждается в главе 13. В данном раз- деле представлен первый метод, создание элементов в памяти. Некоторые элементы можно создать, используя метод createEiement доку- мента или оператор new окна. Оба метода выполняют одинаковые действия и возвращают новый объект элемента. Метод createEiement является неза- висимым от языка механизмом образования элементов. Оператор new по- ставляется для совместимости с Netscape Navigator. Новые созданные объек- ты не поддерживаются в памяти и не связываются с документом до тех пор, пока нс будут явно добавлены в документ. Приведенный ниже пример де- монстрирует использование этих двух методов для создания элемента img: var img = new Image(); var img - document.createEiement("IMG”); Internet Explorer 4.0 позволяет создавать таким образом только три элемента: IMG, Option И Area. Вы можете динамически добавлять новые элементы Option и Area в окна списков и карт изображений, соответственно. Добавление изображений в на- стоящий момент ограничено возможностью предварительной загрузки изо- бражений в кэш. Элемент img сам по себе не может быть добавлен в доку- мент. Вместо этого в процессе добавления изображение загружается в кэш и адрес URL изображения назначается атрибуту sre существующего изображе- ния, что приводит к отображению нового изображения, как показано ниже:
218 Часть II. Структура документа var img = new Image!); img.src = "cool.gif"; // Загружает изображение в фон. document.all.myImage.src - "cool.gif"; // Использует загруженное изображение. Элементы New option и Area могут быть добавлены в документ. Элемент Select представляет семейство options с содержащимися в нем элементами Option, а элемент мар представляет семейство areas, содержащее элементы Area. Данные семейства позволяют динамически добавлять или удалять до- полнительные элементы Option ИЛИ Area. Метод добавления или удаления элементов, а также примеры использования предвари- тельно загруженных изображений, обсуждаются в следующих двух главах. Все осталь- ное содержание элемента Body документа может быть изменено путем прямого изме- нения HTML, что обсуждается в главе 13. Настройка элементов Динамический HTML представляет всю информацию о документе, включая нераспознаваемые элементы и атрибуты. Это может быть использовано для создания определенных пользователем моделей поведения на основе инди- видуальных элементов и атрибутов. Например, можно написать код, кото- рый обеспечивает возможность расширения или сжатия элемента UL, опре- деленного посредством индивидуального атрибута outline. Можно также определить новый тег для указания констант и других элементов поведения в документе. Преимущество данных методов заключается в том, что код становится более структурированным. Разработчику содержания документа больше не требу- ется разбираться в программировании сценариев для добавления сложных элементов в модели поведения элементов. Разработчики могут писать те- перь более изощренный код и документировать использование функцио- нальных возможностей, предоставляемых индивидуальными атрибутами и элементами. Действия по умолчанию Все элементы в элементе Body используют метод click. Сценарии могут ис- пользовать метод click для моделирования'нажатия пользователем кнопки мыши на элементе. Метод запускает событие onclick в элементе и затем вызывает действие, которое должен выполнить элемент по умолчанию при щелчке ио нему мышью. Поскольку событие ev<?nt запускается до возник- новения действия по умолчанию, то разработчик может отменить действие по умолчанию в обработчике события onclick.
Глава 8. Сценарии и элементы 219 Настройка существующих элементов Поскольку объектная модель представляет нераспознаваемые атрибуты и их значения, то к элементу может быть присоединена дополнительная инфор- мация и этой информацией можно легко манипулировать с помощью сце- нариев. Путем добавления нераспознаваемых атрибутов вы можете добав- лять дополнительные элементы в модели поведения существующих элемен- тов. Например, добавить атрибут outline в элемент списка чтобы определить, что список может быть расширен и сжат. Код проверяет, что пользователь щелкнул в списке, в котором определен атрибут outline и вы- полнено соответствующее действие. Использование нераспознаваемых атрибутов является мощным способом моделирования процедуры создания подкласса элемента. Поведение элемен- та может быть полностью настроено и даже изменено путем использования нераспознаваемых атрибутов вместе со всплыванием событий. Проверка наличия атрибута Для изменения поведения элемента могут быть использованы индивидуаль- ные атрибуты. Код может проверять элемент для выяснения наличия атри- бута и выполнять необходимое действие при выполнении данного условия: <IMG I[>"image1" SRC="imgl.gif" dragEnabled» <H) ID="headerl">Test</Hl> <SCRIPT LANGUAGE="JavaScript"» alert(document.all.imagel.getAttribute("dragEnabled") == null); // false alert(document.all.header1.getAttribute("dragEnabled") -= null); // true </SCRIPT> Данный пример демонстрирует добавление индивидуальных атрибутов и простую про- верку их наличия. Код в главе 12 расширяет данный пример путем обеспечения возмож- ности перемещения любого элемента с атрибутом dragEnabled по документу. Индивидуальный атрибут, используемый таким способом, отличается от логического значения. Индивидуальный атрибут определяет модель поведе- ния просто своим присутствием, в отличие от логического значения, кото- рое устанавливает модель поведения, если равно true. Для отключения спо- собности перемещения элемента в предыдущем примере в коде необходимо удалить атрибут dragEnabled С помощью метода removeAttribute, а не просто изменить его значение на false. Определяемые пользователем элементы Поскольку нераспознаваемые элементы представлены в объектной модели, вы можете добавить элементы в документ, который содержит метаппфор-
220 Часть II. Структура документа мацию или другую информацию обработки в структурированной форме. Например, в документ может быть добавлен нераспознаваемый элемент, такой как <iasteditby name= "Scott isaacs">, содержащий имя человека, который последним редактировал документ. На данный элемент теперь может быть установлена ссылка: // Первый экземпляр элемента LastEditBy document.all.tags("LASTEDITBY")(0).getAttribute("name") Ко всем атрибутам нераспознаваемых и распознаваемых элементов можно также обратиться в объектной модели. Данный метод может быть использо- ван для определения повой модели поведения документа без изменения сценариев. Например, если константа требует частого изменения пользова- телем, который не является разработчиком, то можно включить ее в элемент или трактовать как неизвестный атрибут существующего тега. Можно также использовать индивидуальный элемент Sequence для определения последова- тельности появления презентационных эффектов в документе. Данный метод является очень мощным при добавлении новых элементов в модель поведения документа, но следует быть осторожным при использова- нии недействительного кода HTML для хранения информации. В будущем, если определяемый пользователем элемент становится действительным эле- ментом HTML, существует вероятность, что страница будет работать некор- ректно. Константы на основе HTML Используя возможность работы с нераспознаваемыми тегами в динамиче- ском HTML, вы можете описать константы с помощью HTML, а не внутри кода. Преимущество данного метода заключается в том, что константы можно редактировать без необходимости изменения сценариев или знания основ их программирования. Приведенный ниже код использует нераспознаваемый элемент HTMLConstant для хранения всех необходимых констант. HTMLConstant поддерживает три атрибута: id, value и type. Атрибуты id и value необходимы: они определя- ют имя константы и значение по умолчанию. Атрибут type является необя- зательным, поскольку все константы по умолчанию представляют строки. Если требуется указать целое и вещественную константу, то должен быть определен атрибут type. <HTML> <HEAD> <TITLE> Константы на основе HTML </TITLE> CHTMLCONSTANT id="startPosition" value="3" type="integer"> CHTMLCONSTANT id="endPosition" value="2.02” type="float”> CHTMLCONSTANT id="defaultUser" valuer"Scott” type-"string">
Гпава 8. Сценарии и элементы 221 <SCRIPT LANGUAGE»"JavaScript"> , function setupconstants() { // Получение всех констант. , var Constants = document.all.tags("HTMLCONSTANT”); document.—Constants = new Object(); for (var intLoop = 0; intLoop < Constants.length; intLoop++) { var temp = Constants[intLoop]; // Определение типа данных. if ("integer" == temp.type) document._Constants[temp.id] = parselnt(temp.value); else if ("float" == temp.type) document.-Constants[temp.id] = parseFloat(temp.value); else //По умолчанию установлен тип данных String, document.—Constants[temp.id] = temp.value; } ) </SCRIPT> </HEAD> <BODY ONLOAD="setupConstants()"> <H1>HTML-Based Constants</Hl> </BODY> </HTML> На все константы, которые представлены в подобъекте документа constants, может быть установлена ссылка следующим образом: document.—Constants.cans tantID В предыдущем документе константы недоступны до тех пор, пока документ не загружен, поскольку событие onload запускает инициализацию констант, что позволяет описывать константы в документе. Если доступ к константам требуется перед загрузкой документа, то данная функция должна быть вы- звана в ходе анализа страницы. Все константы должны быть определены в исходном коде до текста сценария. Индивидуальные контейнеры содержания Как было показано выше, нераспознаваемые теги могут быть использованы для добавления более контекстуальной информации в документ. Данный метод работает хорошо при создании элементов без содержания. Элементы без содержания не имеют закрывающего тега. Они содержат всю относя- щуюся к ним информацию в атрибутах (подобно элементу img).
222 Часть II. Структура документа Объектная модель не очень хорошо подходит для создания пользовательских контейнеров, что обусловлено способом обработки элементов в дереве ана- лиза. Нераспознаваемые теги не могут иметь дочерние элементы и поэтому с ними не может быть связан текст. Управление и связывание содержания с нераспознаваемым тегом хотя и возможно, но чрезвычайно сложно. Слож- ность является не столько недостатком объектной модели, сколько недос- татком в конструкции HTML. Отсутствует стандартный способ определения того, что нераспознаваемый элемент является контейнером и что должен существовать закрывающий тег. Более того, содержание контейнера будет воспроизводиться всеми браузерами, поскольку элемент нс будет распознаваться и поэтому не может иметь связанного с ним стиля. Хотя обсуждение данного вопроса выходит за рамки данной книги, но су- ществует язык разметки XML (Extensible Markup Language — расширяемый язык разметки), разработанный для обработки расширяемых пользователем элементов. XML использует синтаксис на основе SGML и подобен HTML в том смысле, что может описать разницу между контейнером и пустым эле- ментом. Более подробную информацию об XML можно найти на Web-узле консорциума W3C (World Wide Web Consortium — консорциум Всемирной паутины) (по адресу www.w3c.org) или на Wcb-узле компании Microsoft (www.microsoft.com).
Глава Программирование индивидуальных элементов В главе В были введены элементы сценариев в динамическом HTML. В этой главе рас- сматриваются методы программирования некоторых наиболее часто встречающихся элементов сценариев. Глава Ю описывает методы программирования элементов в формах. В данной главе рассмотрены следующие темы: □ Программирование элементов Body и Frameset. В HTML определены два типа документов: документы с элементами Body для отображения содер- жания и документы с элементами Frameset, разделяющими экран на фреймы для загрузки других документов. Здесь вводятся методы манипу- лирования данными элементами. □ Программирование элемента Anchor. Элементы Anchor выполняют в HTML две функции: являются ссылками для перехода на другие страни- цы или закладками для перехода по данной странице. Здесь обсуждается манипулирование данными типами элементов Anchor и добавление инди- видуальных элементов в их модель поведения. □ Программирование элемента Link. Элемент Link используется для опреде- ления взаимоотношений между документами. Microsoft Internet Explorer 4.0 поддерживает элемент rink дня определения таблиц связанных сти- лей. В данном разделе показано, как определять и использовать индиви- дуальные взаимоотношения между документами. П Программирование элементов img и мар. Динамический HTML представ- ляет многофункциональную объектную модель для манипулирования изображениями и картами изображений. Новые изображения могуг быть загружены в фон и немедленно выведены па экран, и карты изображений могут динамически изменяться и масштабироваться. □ Программирование элемента Marquee. Элемент Marquee (Бегущая строка) является на данный момент специальным элементом Internet Explorer,
224 Часть II. Структура документа который используется для автоматического прокручивания блока текста. Элемент Marquee может быть настроен индивидуально и им можно мани- пулировать с помощью объектной модели динамического HTML. □ Программирование элемента object. Элемент object (Объект) использует- ся для внедрения индивидуального содержания, включая элементы ActiveX и апплеты Java в HTML-документ. Индивидуальное содержание, как и элемент object, может представлять индивидуальную объектную модель, обращение к которой рассматривается в этом разделе. □ Программирование элемента Table. Таблицы используются в двух случаях: для отображения табличных данных и создания сложной схемы размеще- ния элементов. В данном разделе обсуждаются взаимоотношения между основным HTML для таблицы и представлением объектной модели. Программирование элементов Body и Frameset Содержание HTML-документа может быть двух типов: содержание тела (body) или определение набора фреймов (frameset). Первый элемент Восу или Frameset, который появляется в документе, определяет его тип. В обоих случаях используется сходная объектная модель документа. Свойство body Объект document содержит свойство body, которое представляет основу со- держания документа. Имя данного свойства неопределенно, поскольку свойство body может представлять элемент Frameset или Body в зависимости от типа документа. Как объясняется в главе 7, каждый документ имеет элемент Body или Frameset, неза- висимо от того, описан данный элемент явно или нет. Если набор фреймов в документе вложен в другие элементы Frameset, то свойство body представляет самый крайний элемент Frameset в документе. Элемент Body ИЛИ Frameset также находится внутри семейства all документа. Таким образом, к свойству body доступ может быть осуществлен прямо из документа: // Возвращает свойство BODY или FRAMESET в зависимости от типа документа, document.body.tagName; Или доступ может быть осуществлен посредство^! семейства ан: // Для документов, содержащих элемент Body document.all.tags("Body").item(0).tagName; // Возвращает "BODY"
Глава 9. Программирование индивидуальных элементов 225 /* Отображает "true"; демонстрирует, что данные два элемента совпадают */ alert(document.all.tags("Body").item(O) == document.body); // Для документов, содержащих элемент Frameset document.all.tags("Frameset").item(O).tagName; // Возвращает "FRAMESET" /* Отображает "true"; демонстрирует, что данные два элемента совпадают *7 alert(document.all.tags("Frameset").item(O) -= document.body); В приведенном выше коде метод tags возвращает семейство, состоящее из элементов Body или Frameset. Если документ имеет элемент Body, то опреде- ление типа документа (DTD) HTML ограничивает его одним элементом Body, и анализатор игнорирует любые дополнительные элементы. Если до- кумент имеет элемент Frameset, то в документе может находиться множество элементов Frameset. Метод tags возвращает все элементы, начиная с самого крайнего. В любом случае первый элемент в семействе, возвращаемый мето- дом tags, является элементом, который содержится в свойстве body. Код использует элемент item для доступа к данному элементу. Доступ к свойству body Объектная модель создается и представляется одновременно в ходе анализа документа. Пока анализатор не обнаружит тело или набор фреймов в доку- менте, свойство body недоступно, и поэтому свойство body возвращает null. Приведенный ниже код иллюстрирует доступ к свойству body: <HTML> <SCRIPT LANGUAGE^"JavaScript"> alert(document.body == null); // true—предшествует тегу <BODY> </SCRIPT> <BODY> <SCRIPT LANGUAGE»"JavaScript"> alert(document.body == null); 11 false—следует после тега <BODY> </SCRIPT> </BODY> </HTML> Для документов с содержанием body тег <body> не обязательно явно указы- вать в документе. Элемент Body создается по умолчанию, если документ со- держит хотя бы один элемент — или просто текст — который должен быть частью тела. Элементы, которые составляют содержание тела, определены в DTD документа HTML. В главе I объясняется как читать DTD, а дополнительная информация о процедуре анализа документа приведена в главе 7.
226 Часть II. Структура документа Различие между содержанием bodyw frameset Для определения документа можно использовать свойство tagName. Приве- денный ниже код отображает окно, сообщающее тип документа, в данном случае — это набор фреймов: <HTML> <HEAD> <TITLE> Набор фреймов представлен как тело документа </Т1ТЬЕ> </HEAD> ' <FRAMESET ROWS="100%" ONLOAD="alert(document.body.tagName);"> <FRAME SRC=”foo.htm"> </FRAMESET> </HTML> Проверка длины семейства frames в окне нс является точным способом оп- ределения, является ли документ набором фреймов. Документ с элементом Body может содержать элементы iFrame, которые должны быть включены в семейство frames. Окно клиента и размер документа Ширина и высота окна на строке клиента представлены как свойства эле- ментов Body и Frameset. Физический размер (physical size) документа является размером клиентской области — то есть, области экрана, которую занимает документ. Логический размер (logical size) документа определяется размером содержания. Документы, содержание которых не помещается в окне, содер- жат полосы прокрутки. На рис. 9.1 показаны свойства, представляющие фи- зический и логический размеры документа. Данные свойства будут описаны в последующих разделах. Остальные элементы в документе могут представ- лять данные свойства для определения размера элементов. Особые отношении данных свойств с другими элементами в документе обсуждаются в главе 12. Физический размер Физическая ширина и высота документа (типа frameset или body) представ- лены свойствами offsetwidth И offsetHeight Элемента Frameset ИЛИ Body. Физическая ширина и высота измеряют область текущего видимого окна, включая полосы прокрутки. Свойства clientwidth и clientHeight представ- лены ;шя определения размера клиентской области — физического размера, определяемого свойствами offsetwidth и offsetHeight, который меньше на область, занимаемую полосами прокрутки и границами окна. Данные свой- ства доступны только для чтения и их нельзя использовать для изменения размера окна.
Гпава 9. Программирование индивидуальных элементов 227 На рис. 9.1 горизонтальная полоса прокрутки не отображается, так что зна- чения свойств offsetHeight и clientHeight будут одинаковы, если значение границы (border) установлено равным 0. Однако на экране отображается вер- тикальная полоса прокрутки, так что значения свойств offsetwidth и offsetHeight рЭЗЛИЧНЫ. scrollLeft scrollHsight — scrollTop Рис. 9.1. Свойства для определения размера окна и документа Логический размер Четыре свойства элемента Body определяют логический размер документа и положения документе в окне просмотра: scrollwidth, scroll Height, scrollTop и scroliLeft. Логический размер документа представляет общую высоту и ширину документа, а не размер окна браузера, в котором просмат- ривается документ. Данные свойства недоступны или необязательны для документов с набором фреймов, поскольку логический размер набора фреймов эквивалентен его физическому размеру. Свойства scrollwidth и scrollHsight представляют логический размер доку- мента в пикселах, предназначены только для чтения и рассчитываются брау- зером на основе содержания документа. Вы можете изменить значения свойств scrollwidth и scrollHeight путем динамического добавления иди
228 Часть II. Структура документа удаления элементов или изменения размера окна. Изменение размера окна обычно влияет па оба свойства, поскольку содержание адаптируется к новой ширине окна. Свойства scrollTop и scrollLefi представляют значения смещения при про- кручивании логического документа. Они представляют точку в документе, ко- торая отображается в верхнем левом углу окна. Когда горизонтальные и вер- тикальные полосы прокрутки прокручиваются к левой и верхней границам документа, значения свойств scroll Left и scrollTop равны о. Эти свойства допускают чтение/запись и могут быть изменены для прямого прокручивания документа до определенного положения (определяемого в пикселах). Если требуется одновременно установить значения свойств scroiiLeft и scrollTop, то метод scroll окна является наиболее подходящим механиз- мом. поскольку в качестве аргументов он использует обе координаты — и по горизонтали и по вертикали. В сумме данные свойства предоставляют информацию для определения ви- димой части экрана. Просматриваемая область документа может быть легко рассчитана с использованием свойств размера, как показано ниже: upperLeftX = document.body.scrollLeft; upperLeftY = document.body.scrollTop; lowerRightX = upperLeftX + document.body.clientwidth; lowerRightY = upperLeftY + document.body.clientHeight; Свойства, связанные с прокручиванием, также представлены в любом эле- менте с возможностью прокручивания. Например, вы можете установить полосы прокрутки в элементе Div, используя свойство каскадных таблиц стилей (Cascading Style Sheets, CSS) overflow з, а элемент TextArea отобра- жает полосы прокрутки по умолчанию. Если в элементах имеются полосы прокрутки, то они представляют свойства, связанные с прокручиванием, для определения областей прокручивания содержания элементов. Элемент TextArea подробно обсуждается в главе 10, а свойство overflow CSS обсуж- дается в главе 12. События окна Атрибуты элементов Body и Frameset соответствуют всем событиям уровня окна. Например, приведенный ниже код в документе с элементом Body оп- ределяет обработчик событий onload для окна: <BODY ONLOAD="doThis();"> Код для документа типа frameset аналогичен: <FRAMESET ONLOAD=“doThis();" ROWS="*‘,>
Гпава 9. Программирование индивидуальных элементов 229 Если теги <body> или <frameset> используются для определения обработчи- ка событий окна, событие ограничено объектом window, а не объектом body. Данное различие важно, если указатель this используется в обработчике событий. В обработчике событий уровня тела документа указатель this ука- зывает на объект body. В обработчике событий окна this указывает на объ- ект window, даже если обработчик определен в теге <body>. Приведенный ниже код иллюстрирует работу указателя this для события окна (onload) и события тела документа (onclick): <BODY ONLOAD="alert(this == document.body); // false” ONCLICK=”alert(this == document.body); // true"> </BODY> Более того, для событий окна свойство srcElement объекта event содержит значение null. Документ может содержать несколько фреймов, но в документе может быть только один обработчик для каждого события окна. Если несколько элемен- тов Frameset в документе определяют обработчики для события, то выпол- няется только код последнего обработчика. В приведенном ниже примере выполняется только второй обработчик события onload, отображая преду- преждение ь. Событие не генерируется, пока не загружен весь документ. <HTML> <HEAD> <TITLE> Событие onload набора фреймов </TITLE> </HEAD> <FRAMESET ONLOAD="alert('a 1);" ROWS=”100, *”> <FRAMESET ONLOAD="alert ('b'); " COLS="*.*"> <FRAME SRC="a.htm"> <FRAME SRC="b.htm"> </FRAMESET> <FRAME SRC="C.htm”> </FRAMESET> </HTML> Поскольку можно определить только один обработчик для окна, то нельзя указать обработчик для элемента Frame или вложенного элемента Frameset, который работает только для данного определенного элемента. Для предот- вращения данной ситуации, которая, возможно, будет изменена в будущем, обработчики событий окна должны быть определены только для первого элемента Frameset. Событие onresize Событие onresize возникает при изменении физических размеров окна, а не размеров содержания внутри документа body или frameset. Поэтому данное
230 Часть II. Структура документа событие в действительности является событием окна при определении эле- мента Body. Событие onresize также представлено для элементов внутри до- кумента, имеющего определенный размер. В таких случаях событие возни- кает только при изменении физического размера элемента. Первый раз документ запружается в новое окно, и событие onresize не воз- никает. Поэтому код, который используется для размещения документа на основе исходного размера окна, должен быть вызван из события onload. Программирование содержания тела документа Документы, которые содержат элемент Body, могут иметь дополнительные элементы, которые доступны для документов frameset, включая доступ к HTML и текстовому содержанию, которое находится внутри тела документа, и событию onscroii, которое возникает при прокручивании окна. Вы можете написать сценарии для манипулирования текстом в элементе Body tout любом другом элементе в теле документа. Подробнее это обсуждается в главе 13. Событие onscroii Событие onscroii объекта window возникает при прокручивании окна поль- зователем или программой только в документах с элементами Body и не ге- нерируется в документах frameset, поскольку они нс отображают полос прокрутки. Программирование содержания набора фреймов Документ frameset является типом HTML-документа и поддерживается объ- ектной моделью документа. Семейство all документа frameset обеспечивает прямой доступ ко всем его элементам. С помощью семейства all можно по- лучить ДОСТУП К Отдельным атрибутам Элементов Frame и Frameset. Во мно- гих случаях данные атрибуты можно изменять динамически. Число фреймов в наборе постоянно и нс может быть изменено без создания нового документа, но ряд атрибутов элемента Frameset можно изменить. Например, атрибуты rows и cols представляют собой атрибуты, доступные для чтения/записи, что позволяет динамически изменять расположение на- бора фреймов. Эта возможность может быть использована дня добавления элементов индивидуального поведения в традиционный набор фреймов. Приведенный ниже кол создает индивидуальную схему размещения, что по- зволяет пользователю выбирать страницы из набора страниц. Данный при- мер отключает возможность изменения размеру фреймов и автоматически разворачивает фрейм, в котором пользователь щелкнул мышью. Данная схема размещения требует включения небольшого по объему кода в набор фреймов и каждый документ.
Глава 9. Программирование индивидуальных элементов 231 <HTML> <TITLE> Перемещающиеся фреймы </TITLE> <SCRIPT LANGUAGE*-" JavaScript "> var defSize = 25; if (f==_current) return; // Проверка состояния _current = f; function display(f) { var newRows = "" // Определение местоположения первого фрейма в семействе all var elFrame_ = document.all.tags ("FRAME"); for (var intFrames=O; intFrames< frames.length; intFrames++) { var curF = frames[intFrames].document; if (curF.body == f.document.body) { I/ Предоставление всего пространства выделенному фрейму newRows+=”*,”; */ Увеличение заголовка curF.all.header.style.fontSize="200%"; /* Включение полос прокрутки в активном фрейме путем доступа к элементу Frame. */ eiFrame[intFrames].scrolling="yes"; ) else ( // Установка размера по умолчанию newRows+=defSize.toString() + // Сброс изменений размера и шрифта заголовка curF.all.header.style.fontSize=""; // Отключение прокручивания , elFramefintFrames].scrolling="no"; ) ) document.body.rows=newRows; ) </SCRIPT> </HEAD> <FRAMESET ROWS="*, 25, 25"> <FRAME SRC="home.htm” NORESIZE> <FRAME SRC="news.htm" NORESIZE SCROLLING="No"> <FRAME SRC="info.htm" NORESIZE SCROLLING="No"> </FRAMESET> </HTML> На рис. 9.2 продемонстрирована работа данного кода. Когда пользователь щелкает по заголовку News или Information, то другие фреймы автомати- чески сворачиваются и на экране разворачивается выбранный фрейм.
232 Часть II. Структура документа Рис. 9.2. Пример автоматически всплывающих фреймов В каждом документе в наборе фреймов обработчик событий onfocus должен вызывать процедуру display. Для вызова функции следует сослаться на свойство parent документа: <!— Для каждого документа в наборе фреймов должно быть определено собы- тие onfocus. —> <BODY ONFOCUS="parent.display(this);"> Кроме того, в каждом документе в наборе фреймов идентификатор ID пер- вого параграфа должен иметь значение header. Текст в этом параграфе будет увеличен при получении документом фокуса. Данный пример демонстрирует модификацию индивидуальных фреймов. Элемент Frame в семействе all документа отличается от содержания семей- ства окна frames. Семейство frames окна возвращает экземпляр окна, соз- данный на основе источника документа. Элемент Frame в семействе all представляет фрейм как определенный источником HTML п используемый лая создания окна. Изменение элемента Frame может привести к изменению окна и сю содержания. Например, можно вручную активизировать или от- ключить полосы прокрутки. Полосы прокрутки были отключены в данном примере, так что они не мешают сжатому просмотру заголовка документа. Программирование элемента Anchor Элемент Anchor в HTML служит двум целям: для определения ссылок пере- хода к адресам URL и для установки закладок внутри документа. Элемент Anchor ведет себя как ссылка, если определен его атрибут href, или как за- кладка, если определено значение атрибута name* <А HREF="http://www.insideDHTML.com#Chapter2"><!— Link —></А> <А NAME="Chapter2"><!— Bookmark —></А>
Гпава 9. Программирование индивидуальных элементов 233 Семейство all документа содержит все элементы Anchor. Документ имеет два дополнительных семейства, которые по отдельности содержат ссылки и закладки. Ссылки представлены семейством links, а закладки — семейством anchors. Простой элемент Anchor может находиться в обоих семействах, ес- ли определены атрибуты name и href. Свойства href и name могут быть изменены в коде, так что объект якоря мо- жет динамически переключать семейства. Например, если якорю с пустым свойством href назначается строка, то он автоматически добавляется в се- мейство links и автоматически воспроизводится на экране как ссылка. Не- зависимо от типа якоря и семейства, в котором он находится, объект якоря представляет тот же набор свойств, методов и событий. ( Примечание ) Начиная с этого места, якоря, определенные как <А NAME->, называются за- кладками, а якоря, определенные как <д HREF-', называются ссылками для различия между двумя типами якорей. Данные ссылки отличаются от элемента Link, который обсуждается ниже в разделе данной главы "Программирование элемента Link". Тег <link> определяет элемент Link. Свойство href Объект якоря имеет ряд свойств, которые содержат части URL, представ- ленные СВОЙСТВОМ href. Свойства protocol, hostname, pathname, search И hash ссылаются на индивидуальные части URL, а свойство host содержит имя хоста и номер порта. Данные свойства, которые также принадлежат к объекту location, описаны в главе 4. Якоря и базовый HREF Между значениями href, определенными относительно, и объектной моде- лью существуют интересные отношения. Относительный href является ад- ресом URL, который не начинается символами // (например, href= "goHere.htm”/ Всем относительным href предшествует местоположение но умолчанию. Если не определено обратное, то местоположение по умолча- нию является местоположением текущего документа. Вы можете использо- вать элемент Base для изменения местоположения по умолчанию. Для отно- сительных URL, назначенных атрибутам, местоположение по умолчанию добавляется при анализе документа. Местоположение по умолчанию нс до- бавляется в относительные URL, назначенные свойствам сценариями, пока не будет сделана ссылка на URL. Приведенный ниже код иллюстрирует данные положения: <HTML> <HEAD>
234 Часть II. Структура документа <TITLE> Демонстрация базового HREF </TITLE> <BASE HREF="http://scotti/"> </HEAD> <BODY> <A HREF="pagel.htm">page 1</A> <A HREF=”http://ji/page2.htm">page 2</A> <SCRIPT LANGUAGE=”JavaScript"> alert(document.links(0].href); // http://scottiZpagel.htm alert(document.links[1].href); // http://ji/page2.htm document.links[0].href = "newpage.htm"; alert(document.links[0].href); // newpage.htm <-/SCRIPT> </BODY> </HTML> Атрибут HREF, определяемый сценарием Атрибут href элемента .Anchor иначе может быть определен как строка кода, которая должна быть выполнена. Данный метод полезен, когда фрейм со- держит короткую строку, поскольку уменьшается число циклов обмена ин- формацией между сервером и клиентом. Например, когда пользователь на- жимает следующий якорь, запускается простой документ, отображающий строку "Hello, world!": <А HREF="JavaScript:'Hello, world! Свойство protocol представляет собой имя языка, после которого указаны точка с запятой и pathname является остальной частью строки. Свойство href содержит всю строку с соответствующими escape-последователыюстямн (такими как % 20 для каждого пробела). Определяемые сценарием атрибуты href выполняются после окончания ге- нерации событий onclick, Кроме того, поскольку атрибут href не является событием, то объект event недоступен в момент выполнения определяемого сценарием атрибута href. (~ Примечание При использовании VBScript для определяемых сценарием атрибутов HREF следует быть осторожным. Netscape Navigator распознает только язык JavaS- cript и будет отображать ошибку перехода, если определен VBScript. События элемента Anchor Элемент Anchor поддерживает ряд стандартных событий, которые возникают при нажатии пользователем кнопки мыши, перемещении указателя мыши и ввода значения в якоре. События, которые могут быть инициированы эле-
Гпава 9. Программирование индивидуальных элементов 235 ментом Anchor, зависят от того, является ли якорь ссылкой или закладкой. Если элемент Anchor не может функционировать как источник события, то он никогда не будет определен как srcElement, если событие будет всплы- вать. Таблица 9.1. События элемента Anchor Событие Источник Событие Источник onblur Якоря ссылок onkeyup Якоря ссылок onclick Все якоря onmousedown Все якоря ondbldick Все якоря onmousemove Все якоря onfocus Якоря ссылок onmouseout Все якоря onkeydown Якоря ссылок onmouseover Все якоря onkeypress Якоря ссылок onmouseup Все якоря С помощью всплывания событий элемент Anchor может получить событие от дочернего события (такого как изображение в якоре), даже если он явно не поддерживает его. В приведенной выше таблице перечислены события, для которых все типы якорей могут являться источником. Все события мо- гут быть определены как атрибуты элемента, посредством синтаксиса <script for=event=> пли с помощью свойств элемента Anchor. Чтобы слу- жить источником для событий фокуса и клавиатуры, элемент должен иметь возможность получать фокус. Якоря, которые являются ссылками, могут получать фокус. Закладки не могут получать фокус. По умолчанию результатом нажатия ссылки является переход к якорю. Дан- ное действие может быть изменено для индивидуальной настройки обработ- ки страницей ссылки. Приведенный ниже код отменяет действие по умол- чанию определенной ссылки: <А HREF="foo.htmttlOO” ONCLICK="event.returnvalue = false;"» Чтобы обеспечить совместимость с другими браузерами, следует вернуть значение прямо: <А HREF="foo.htm#100" ONCLICK="return false;"» В целом якоря могут быть изменены на уровне документа путем обработки события onclick документа, как показано в приведенном ниже коде. Дан- ный метод работает, поскольку стандартные события, за исключением собы- тий onblur и onfocus, всплывают по иерархии документа. CSCRIPT FOR="document" EVENT="onclick()" LANGUAGE^"JavaScript"» // Объект события содержит глобальную информацию для обработчика событий.
236 Часть II. Структура документа if ("А" == event.srcElement.tagName) { event.returnvalue = false; // Запись индивидуального обработчика кода для якоря. ) </SCRIPT> Последовательность событий такова, что событие ondbiciick возникает по- сле события onclick. Определить, был ли произведен по ссылке двойной щелчок, можно, только отменив действие по умолчанию одиночного щелч- ка, поскольку последовательность событий фиксирована. Невозможно на- писать обработчик событий для ссылки, который выполняет действие по умолчанию для события нажатия кнопки и другое действие для двойного нажатия кнопки, поскольку ссылка уже осуществляет переход к указанному документу до возникновения события ondbiciick. Поэтому использование события ondbiciick для ссылки сильно ограничено, и большинство взаимо- действий с якорями выполняются при помощи события one] ick. Настройка ссылок на многочисленные фреймы Одним из методов добавления элементов индивидуального поведения в .мо- дель якоря является определение нескольких новых атрибутов для элемента Anchor. Этот метод моделирования выделения подкласса был введен в главе 8. В данном разделе продемонстрировано расширение традиционного поведения якорей. В простом примере, который приведен ниже, реализуются основы требуе- мого элемента HTML и наборов фреймов — способность указывать в каче- стве цели многочисленные фреймы в одном якоре. Данный пример демон- стрирует, как авторы могут увеличивать функциональные возможности страницы без необходимости ожидания введения поддержки данной воз- можности в браузеры. Приведенный ниже код добавляет два определяемых пользователем атрибута в элемент Anchor: mhref И mtarget. Оба атрибута используют список значе- ний, разделенных точкой с запятыми — для mhref это список URL, а для mtarget — список местоположений для данных URL. Когда пользователь выполняет щелчок по якорю, код сначала проверяет, имеет ли якорь эти специальные атрибуты, и при их наличии код заменяет поведение по умол- чанию одиночной ссылки на индивидуальный код ссылки. <HTML> <HEAD> <TITLE> Указание в качестве цели многочисленных фреймов </TITLE> <SCRIPT LANGUAGE="JavaScript"> function checkElementTree(el, strTag)4 ( /* Данная простая функция просматривает дерево от элемента el ищет элемент с тегом strTag.
Глава 9. Программирование индивидуальных элементов 237 Возвращается первый найденный элемент. •/ while ("HTML" != el.tagName) ( if (strTag == el.tagName) return el; el = el.parentElement; I return null; } function multiJumpO ( // Поиск якоря. var el = checkElementTree(event.srcEiement, "A"); if (null != el) { // Found an anchor. // Проверяет, имеет ли якорь множество целой. if ((null != el.getAttribute("mhref")) &S (null != el.getAttribute("mtarget"))) ( event.returnvalue = false; var mhref = new ArrayO; var mtarget = new ArrayO; // Разлагает атрибуты на массивы, mhref - el.getAttribute("mhref").split ("; "); mtarget = el.getAttribute("mtarget").split("; "); /* Убедитесь в совпадении числа целей и адресов BRL.*/ if (mtarget.length == mhref.length) for (var intLoop ~ 0; intLoop < mtarget.length; intLoop++) if (null parent[mtarget[intLoop]]) parent[mtarget[intLoop]].location.href = mhref[intLoop]; } > ) </SCRIPT> </HEAD> <BODY ONCLICK-"multiJump();"> <A HREF="#" mhref="http://www.microsoft.com; http://www.netscape,com" mtarget="left; right"> Web-узлы браузеров </A> </BODY> </HTML> Данный код работает только для фреймов, которые находятся в равных от- ношениях с содержащим их фреймом. Для того чтобы данный код работал
238 Часть II. Структура документа для фреймов, которые находятся в любом месте иерархии набора фреймов, следует написать код, который будет моделировать поисковый алгоритм, используемый браузером для поиска иерархии окон. Выделение подклассов элементов с определенными пользователем атрибу- тами является одним из наиболее мощных способов использования возмож- ностей динамического HTML. Это позволяет легко настраивать элементы без жестких настроек в HTML или языке написания сценариев. Индивиду- альные атрибуты могут быть определены для идентификации нового пове- дения и код может искать данные идентификаторы и обрабатывать элемен- ты соответственно. Псевдоклассы для якорей Таблицы стилей обеспечивают метод определения стилей для трех состоя- ний ссылки: просмотренная (visited), не просмотренная (not visited) и актив- ная (active). Данные состояния могут иметь различные стили, которые мож- но установить, используя псевдоклассы (pseudoclass) в CSS. Псевдоклассы обеспечивают метод повышения уровня взаимодействия с пользователем без добавления кода. Более подробную информацию о псевдоклассах и языке CSS вы можете найти в главе / или в спецификации CSS на Web-узле консорциума W3C. Использование псевдокласса позволяет прямо определить просмотренную ссылку. Других методов в языке сценариев в настоящее время нет. Поэтому отсутствует простой способ условного программирования ссылок на основе того, были они просмотрены или нет. Удаление якорей Простое назначение пустой строки свойству href или name не приводит к удалению элемента Anchor из документа. Однако данный метод позволяет удалить элемент из семейства links или anchors. (Удаляемый элемент всегда остается в семействе all). Элемент Anchor и его содержание могут быть полностью удалены из доку- мента путем использования свойств outerHTML или outerText. Для удаления влияния якоря с сохранением его содержания может быть использован объ- ект TextRange. Приведенный ниже код демонстрирует манипулирование объектом TextRange. Объект TextRange и его методы подробно обсуждаются в главе 14. <SCRIPT LANGUAGE="JavaScript"> function removeAnchor(aElement) { // Удаляемый якорь передается как аргумент.
Глава 9. Программирование индивидуальных элементов 239 // Создание объекта TextRange. var tr = aElement.parentTextEdit.createTextRangcO; // Размещение элемента Anchor в объекте TextRange. tr.moveToElementText(aElement) ; // Выполнение команды для удаления элемента Anchor, tr.execCommand("Unlink", false); ) </SCRIPT> Программирование элемента Link В предыдущем разделе показано как программирован, элемент Anchor. кото- рый представляет закладку или ссылку. HTML также предоставляет элемент Link, который может быть использован для определения взаимоотношений между различными тинами документов. В данном разделе рассматривается метод определения взаимоотношении между документами с использованием элемента Link и атрибутов rel и href, к которым можно обратиться с помо- щью сценариев. На момент написания книги браузер Internet Explorer использовал отноше- ния ссылок для таблиц стилей. Однако написав несколько сценариев, вы можете использовать атрибут rel для определения других отношений. Опре- деление отношений не только делает Web-узел более управляемым, ио также может обеспечить доступ к Web-узлу инструментов анализа Web-узлов. Приведенный ниже пример демонстрирует как создать панель перехода, ко- торая читает все элементы Link документ;! для перехода между страницами. Панель перехода полезно использовать, когда представлен ряд документов. Панель перехода и панели содержания определены посредством простого набора фреймов. При загрузке нового документа вызывается функция, об- новляющая кнопки перехода на основе ссылок нового до- кумента. На рис. 9.3 показана работа панели перехода. Доступной ь кнопок в верхней панели и место назначения, на которое они указывают, определяется отношениями Link. E .............. ...... | Йе £Л View fie. Help . . Table of Contents Link ReMlionthip* * MictoMft Internet Explore» The destinations of the navigation buttons arc defined in Link elements in the document displayed. Buttons are disabled if their destinations are not defined in the current document. For example, the Previous button is disabled because no document exists sequentially before the table of contents Рис. 9.3. Панель перехода на основе элементов Link
240 Часть II. Структура документа Документ links.htm Документ links.htm, показанный в приведенном ниже коде, определяет на- бор фреймов и содержит основной код для управления отношениями между ссылками на странице и панелью перехода. Каждый документ, который отображается внутри фрейма, должен вызвать функцию setupLinks после своей загрузки для обновления панели перехода в окне перехода. При вы- грузке страницы метод clearLinks должен быть вызван для отключения всех кнопок отношений, чтобы гарантировать, что все ссылки указывают па дей- ствительные документы, если пользователь переходит к странице, которая не определяет отношения. <HTML> <HEAD> <TITLE> Отношения ссылок </TITLE> «SCRIPT LANGUAGE-"JavaScript"> function setButton(b, dis, title, href) ( b.disabled = dis; b.title - title; b.href = href; I function clearLinks() ( var navDoc = window.navigation.document.all; // Инициализация кнопок путем их отключения и удаления их // надписей. with (navDoc) ( setButton(previous, true, "”); setButton(next, true, "”); ) } function setupLinks(doc) ( // Вызывающий документ должен быть передан функции. // Получение всех элементов Link. var links = doc.all.tags("LINK"); var navDoc = navigation.document.all; clearLinks(); for (var intLink = 0; intLink < links.length; intLink++) ( var el = links(intLink]; if ("previous” == el.rel) ( /* Если предыдущие отношения были определены, то обновите кнопки. */ setButton(navDoc.previous, false, el.title, el.href); ) if ("next" == el.rel) (
Глава 9. Программирование индивидуальных элементов 241 /* Если определено следующее отношение, то обновите кнопки. */ setButtonfnavDoc.next, false, el.title, el.href); } ) } c/SCRIPT> C/HEAD> CFRAMESET ROWS="28, *" BORDER=0> CFRAME SRC="navigate.htm" NAME="navigation" SCROLLING=NO> CFRAME SRC="contents.htm" NAME="contents"> c/FRAMESET> </HTML> Документ navigate.htm Приведенный ниже код создает панель перехода: <HTML> <HEAD> <TITLE> Панель перехода </TITLE> CSTYLE TYPE="text/css"> body {margin-top:2pt; margin-left:2pt; background:gray) input {font-weight:bold) </STYLE> </HEAD> <BODY> CINPUT TYPE=BUTTON VALUE="TOC,r TITLE="Table of Contents" ONCLICK="top.contents.location - 'contents.htm';”> CINPUT TYPE=BUTTON ID=”previous” VALUE=" < " ONCLICK=’’parent. contents. location = this.href;"> CINPUT TYPE=BUTTON ID="next” VALUE=" > “ ONCLICK="parent.contents.location = this.href;"> C/BODY> C/HTML> ( ~ Примечание j Кнопки в данном примере разделены с дополнительными пробелами ними, по- скольку символы перехода на новую строку разделяют их теги в коде. Для уда- ления пробелов между кнопками удалите символы перехода на новую строку и все пробелы между элементами input. Документ contents, htm ч Приведенный ниже код представляет собой файл содержания, который определяет отношения ссылки со следующим документом в последователь-
242 Часть II. Структура документа пости. При загрузке данный документ должен вызвать функцию setupLinks ДЛЯ обновления доступных ССЫЛОК, а при выгрузке — функцию clearLinks. <HTML> <HEAD> <TITLE> Содержание </TITLE> <!— Определен только переход вперед. Кнопка Previous будет отключена для данного документа. —> <LINK REL="next" HREF=”chapterl.htm" TITLE=”Chapter 1"> </HEAD> <BODY ONLOAD="parent.setupLinks(window.document) ; " ONUNLOAD="parent.clearLinks();"> <Hl>Table of Contents</Hl> </BODY> </HTML> Пример демонстрирует два простых отношения, но его легко расширить пу- тем добавления новых отношений для обеспечения улучшенной панели ин- струментов в окне перехода. Программирование элементов IMG и Мар Изображения и карты изображений (image maps) полностью программиру- ются в Internet Explorer 4.0. Вы можете изменить атрибут SRC и размер изо- бражения, а также изменять, добавлять и удалять элементы Area из карты изображений. Объектная модель также позволяет асинхронно загружать но- вые изображения в фоновом режиме во время работы пользователя со стра- ницей. В данном разделе представлены методы загрузки изображений и ма- нипулирования элементом img и связанными с ними картами изображений. Анимация изображений Одним из распространенных методов анимирования изображений является изменение изображения при подведении и отведении указателя мыши к элементу. В Internet Explorer 4.0 данная задача выполняется тривиально — используются события onmouseover и onmouseout на самом элементе img: <IMG SRC="start.gif" ONMOUSEOVER="this. sre = 'over.gif';" ONMOUSEOUT=”this.sre = 'start.gif Netscape Navigator проигнорирует данный код, поскольку он на данный мо- мент нс поддерживает события onmouseover и onmouseout для элемента img. Однако Netscape Navigator поддерживает данные события для элемента Anchor. Поэтому после некоторого размышления можно изменить приве-
Гпава 9. Программирование индивидуальных элементов 243 денный выше сценарий для работы в других браузерах. Помещая элемент IMG в элемент Anchor, браузеры Netscape Navigator версий 3.0 и более позд- ней и Internet Explorer 4.0 будут правильно изменять изображение: <А HREF="" ONMOUSEOVER="document.mylmage.sre = 'over.gif’;" ONMOUSEOUT="document.myImage.src = ’start.gif' < <IMG BORDER=0 NAME="myImage" SRO"start.gif"> </A> Атрибут border=o необходимо добавить, так как иначе по умолчанию вокруг изображения будет нарисована рамка. И хотя данный метод поддерживается и в Netscape Navigator и в Internet Explorer, имеется одно ключевое отличие. Поскольку не указан размер изображения, то в Internet Explorer размер кон- тейнера изображения автоматически изменяется в соответствии с размером изображения с одновременным изменением окружающего содержания. В Netscape Navigator размер изображения фиксирован, когда загружается первое изображение, так что следующее изображение будет масштабиро- ваться для соответствия указанному размеру. Для преодоления данного рас- хождения убедитесь, что изображения имеют одинаковый размер или ука- жите значения атрибутов width и height в элементе img. При выполнении приведенного выше кода может наблюдаться заметная за- держка при первой загрузке второго изображения. Динамический HTML поддерживает фоновую предварительную загрузку изображения, так что изображение будет доступно для использования немедленно. Последовательность изображений Для изменения изображения могут быть использованы события таймера вместо генерируемых пользователем событий. Динамический HTML упро- щает создание планировщика изображений, который чередует изображения по истечении определенного промежутка времени. Изображения могут быть предварительно загружены с помощью специального конструктора изобра- жений и атрибут src элемента img может быть изменен динамически. Приведенный ниже код показывает применение данного метода для созда- ния доски объявлений на клиентской стороне, которая циклически воспро- изводит изображения с определенным интервалом. Эта схема использует нераспознаваемые элементы для определения списка объявлений. Преиму- щества данной модели заключаются в том, что можно добавлять новые и удалять устаревшие рекламные объявления без изменения кода. Другой ме- тод, который используется в данном примере, заключается в предваритель- ной загрузке изображений перед назначением атрибута src, чтобы гаранти- ровать плавный переход от одного изображения к другому. Добавлен также механизм восстановления после ошибок для пропуска изображения в случае отсутствия возможности его загрузки.
244 Часть II. Структура документа <HTML> <HEAD> <TITLE> Последовательное отображение рекламных объявлений </TITLE> <I — Дополнительные объявления могут быть добавлены без расширения данного списка. —> <ADLIST src=”adl.gif" duration=3000> <ADLIST src="ad2.gif" duration=5000> <ADLIST src=”ad3.gif"> <ADLIST src~”ad4.gif" duration=1000> «SCRIPT IANGUAGE="JavaScript"> var adSet = document .all. tags ("ADUST") ; adSet.current = 0; var nextimage = document.createElement("IMG"); function preLoad() { // Получение следующего изображения. // Если возникает ошибка, то следующее изображение // пропускается. /‘Всегда устанавливать обработчики событий изображений перед назначением атрибута SRC для гарантии отсутствия пропусков событий. */ nextimage.опеггог = preLoad; nextImage.src = adSet[adSet.current].getAttribute("src"); // Атрибут duration определяет длительность отображения // изображения. nextimage.duration = adSet[adSet.current].getAttribute("duration") ; if (null == nextimage.duration) // If not specified, use nextImage.duration = 2000; // default 2 seconds. if (++adSet.current == adSet.length) adSet.current = 0; // Start over, t function skiplmage() { // Загружено ли следующее изображение? if (nextimage.complete) { document.all.ad.src = nextImage.src; var duration = nextimage.duration; preLoad();0 window.tm = setTimeout('skiplmage()', duration); ) else // Быстрый повтор до тех пор, пока изображение доступно, window.tm = setTimeout('skiplmage()’, 10); ) preLoad(); </SCRIPT>
Гпава 9. Программирование индивидуальных элементов 245 </HEAD> <BODY ONLOAD="window. tm = setTimeout('skiplmage()', 1);" ONUNLQAD=”clearTimeout(window.tm);"> <IMG ID="ad" SRC="ad4.gif" STYLE="border:2px solid navy"> </BODY> </HTML> Internet Explorer 4.0 также поддерживает создание новых изображений для ФОНОВОЙ ЗагруЗКИ С ПОМОЩЬЮ оператора now ПОМИМО метода createEiement. Данный оператор поддерживается для совместимости с реализацией JavaScript в Netscape Navigator. Оператор new является независимым ог языки методом создания новых элементов. Например, в приведенном выше коде строка nextimage = document.createEiement("IMG"); может быть записана следующим образом: nextImage = new Image(); Однако поскольку Netscape Navigator не использует индивидуальные эле- менты в сценариях, то данный код чередования рекламных объявлений тре- бует дальнейшей модификации для запуска в Netscape Navigator: информа- ция о графических изображениях в рекламных объявлениях должна хра- ниться в сценарии, скорее всего в массиве, а не в индивидуальных элементах AdList. Карты изображений Карты изображений (image maps) позволяют разделить изображение на об- ласти, содержащие ссылки па различные документы. Чаще всего карты изо- бражений используются для создания видимых карт перехода. Когда поль- зователь выполняет щелчок по определенной области изображения, дейст- вие по умолчанию осуществляет переход на указанную страницу. Используя модель событий, вы можете заменить действие по умолчанию па индивиду- альные действия. Определение карты изображения HTML предоставляет два типа карт изображений: серверные и клиентские. Серверная карта изображения определяется путем добавления атрибут ismap в изображение и создания файла карты изображения на сервере. Когда пользователь щелкает по изображению, то значения координат ху отправ- ляются на сервер. Серверная карта изображения имеет два внутренних не- достатка: как правило, требуется передача информации на сервер и не обес- печивается простой доступ, поскольку области нажатия (click regions) неиз- вестны браузеру или сценариям.
246 Часть II. Структура документа Клиентские карты изображений используют элемент мар и не требуют обме- на информацией с сервером. Они позволяют браузерам выделять области нажатия изображения. Элемент мар содержит набор элементов Area, которые определяют координаты для каждой области нажатия. Элементы мар должны быть названы, чтобы их можно было связать с изо- бражением. Если указано имя элемента мар, то любое количество изображе- ний может быть связано с ним посредством атрибута usemap изображений. Значение атрибута usemap должно быть определено как ссылка на адрес. На- пример, приведенный ниже код связывает изображение с картой изображе- ния, названной diagram: <IMG SRC="diagram.gif" USEMAP="#diagram"> Клиентские карты изображении и их синтаксис продемонстрированы в приведенных ниже примерах. Однако полный синтаксис для определения серверной /ми клиентской карты изображения выходит за рамки данной книги. Более подробное описание синтак- сиса карт изображений можно найти в справочнике по HTML или на И^еЬ-узле компа- нии Microsoft (www.microsoft.com). Карты изображений и события Вы можете поместить карту изображения в любом месте документа незави- симо от связанного с ним изображения. Поскольку одна карта изображения может совместно использоваться несколькими изображениями, то объектная модель динамического HTML поддерживает специальные отношения между изображением и соответствующей картой изображения при возникновении событий. При возникновении события в карте изображения элемент Area получает событие, затем событие получает элемент мар и затем — элемент img, по ко- торому щелкнул пользователь. После получения события изображением со- бытие продолжает подниматься вверх через родительские элементы изобра- жения. Таким образом, может быть совместно использована одна карта изо- бражения и события или, в зависимости от обстоятельств, изображение само может изменять или добавлять элементы собственного поведения в карту изображения. Элементы, которые содержат карту изображения в исходном коде HTML, могут никогда не получить события, которые возникли в карте изображения. Доступ к карте изображений Свойство useMap элемента img содержит имя связанной карты изображения, которому предшествует символ #. Удалив предшествующий символ Н из свойства иземар, можно обратиться к карте изображения. Свойство useMap допускает операции чтения/записи, что позволяет динамически связывать карты изображений с изображением. Приведенный ниже код демонстрирует
Гпава 9. Программирование индивидуальных элементов 247 простую функцию для получения связанной карты изображения из элемен- та img: • function getMap(ellmage) { If Убедитесь, что для изображения определена карта, if (null != ellmage.useMap) ( // Удаляет первый символ # из закладки. var strMap = ellmage.useMap.substring(1); // Возвращает элемент с указанным именем, return document.all[strMap]; } else return null; Динамическое изменение карты изо- бражения позволяет обеспечить раз- личный уровень детализации в слож- ном изображении или географической карте. На рис. 9.4 проиллюстрирован метод обеспечения большей управляе- мости набором элементов (в данном случае, городами и штатами) путем предоставления пользователю возмож- ности выбора подмножества интере- сующих его элементов. Данный метод отбора становится еще более мощным при использовании его для разделения между перекрывающимися областями. Рис. 9.4. Изображение может иметь две различных карты изображения Поскольку города в данном примере перекрывает штаты, то выбор пользо- вателя может быть затруднен. Выбор можно упростить, предоставив пользо- вателю возможность выбора между городами и штатами. Данный метод от-
248 Часть II. Структура документа бора легко реализовать путем переключения между двумя картами изобра- жений в зависимости от сделанного пользователем выбора, как показано в приведенном ниже примере: <HTML> <HEAD> <TITLE> Переключение карт изображений </TITLE> «SCRIPT LANGUAGE-"JavaScript”> function setMap(mapName) ( document.all.mapImage.useMap = mapName; } </SCRIPT> </HEAD> <BODY> <P>Select From:<BR> «INPUT TYPE=RADIO NAME="feature" ID="States” Value="#States" ONCLICK="setMap(this,value)CHECKED> «LABEL FOR="States">States«/LABELXBR> «INPUT TYPE=RADIO NAME="feature" lD="Cities" Value="#Cities" ONCLICK="setMap(this.value);"> «LABEL FOR="Cities”>Cities</LABELX/P> «PXIMG ID="mapImage" SRC=”places.gif" BORDER=0 WIDTH=197 HEIGHT-448 USEMAP="#States”x/P> «MAP NAME="Cities"> «AREA SHAPE="POLYGON" HREF="la.htm" COORDS="108, 408, 164, 407, 165, 388, 111, 387, 109, 361, 86, 361, 73, 394, 94, 411"> «AREA SHAPE="POLYGON" HREF=”sanfran.htm" COORDS="12, 301, 58, 275, 75, 305, 80, 301, 87, 314, 92, 326, 119, 329, 121, 340, 45, 341, 44, 328, 9, 328"> «AREA SHAPE="POLYGON" HREF="portland.htm" COORDS="34, 120, 47, 120, 49, 115, 68, 115, 69, 123, 86, 127, 86, 131, 140, 131, 137, 144, 86, 145, 91, 162, 22, 160, 22, 148, 26, 144”> '«AREA SHAPE="POLYGON" HREF="seattle.htm" COORDS="73, 86, 93, 84, 92, 73, 125, 73, 123, 59, 92, 57, 87, 43, 93, 22, 82, 2, 71, 21, 79, 45"> ' </MAP> «MAP NAME="States"> «AREA SHAPE="POLYGON" HREF="california.htm" COORDS="14, 204, 18, 200, 83, 209, 79, 278, 166, 366, 171, 403, 167, 409, 166, 419, 163, 423, 164, 430, 166, 436, 161, 439, 115, 438, 112, 433, 110, 420, 97, 409, 92, 401, 82, 399, 77, 392, 56, 385, 54, 369, 46, 357, 46, 352, 34, 338, 39, 327, 35, 322,
Гпава 9, Программирование индивидуальных элементов 249 32, 309, 34, 297, 25, 297, 24, 288, 14, 273, 15, 255, 9, 235, 12, 224, 12, 221, 16, 21б"> <AREA SНАРЕ="POLYGON" HREF="oregon.htm" COORDS=”16, 199, 136, 216, 140, 178, 143, 171, 138, 164, 153, 132, 147, 122, 103, 120, 80, 123, 72, 121, 55, 121, 51, 109, 37, 105, 22, 163, 23, 166, 18, 173, 14, 189"> <AREA SHAPE="POLYGON" HREF="washington.htm" COORDS="33, 50, 64, 64, 57, 74, 57, 86, 63, 81, 70, 65, 66, 41, 152, 55, 147, 123, 100, 119, 86, 124, 74, 120, 56, 119, 51, 108, 40, 104, 36, 99, 43, 93, 37, 87, 41, 84, 36, 80"> </MAP> </BODY> </HTML> Примечание j Каждый список координат в элементах Area должен занимать одну строку, иначе код будет выполняться некорректно. Списки в приведенном выше коде разде- лены для размещения на странице. Символы перехода строки (..), которые ука- зывают переход строки, не должны находиться в исполняемом коде. Доступ к элементам Area Динамический HTML представляет элементы Area посредством следующих семейств: □ Семейство links документа □ Семейство all документа □ Ссмсйтсво areas элемента мар, содержащего элементы Area Сценарии могут обращаться к атрибутам элемента Area любым из перечис- ленных выше трех способов для их динамического изменения. Элемент Area имеет атрибут href, который содержит адрес URL и представляет те же свойства, содержащие части данного адреса, которые представлены объек- тами location и anchor. Семейство areas обеспечивает дополнительные функциональные возможности, что позволяет добавлять и удалять новые элементы Area из карты изображения. Поддерживается динамическое изменение координат и форм внутри карты изображения, но обычно проще п более технологично определить много- численные карты изображений в документе и переключаться между ними. Исключение составляет случай, когда вы рассчитываете новые области на- жатия на основе старых областей путем простого преобразования. Напри- мер, если изображение может быть масштабировано, то проще масштабиро- вать изображение и карту изображения. Если в изображении поддерживает-
250 Часть II. Структура документа ся функция zoom, то связанная карта изображения должна также быть мас- штабирована вместе с изображением: <HTML> <HEAD> <TITLE> Динамическое масштабирование карт изображений </TITLE> «SCRIPT LANGUAGE-"JavaScript"> function getMap(ellmage) { Il Убедитесь, что для изображения определена карта изображения, if (null != ellmage.useMap) { I/ Удаляет первый символ # из закладки. var strMap = ellmage.useMap.substring(l); II Возвращает элемент с указанным именем, return document.al1(strMap); ) else return null; ) function zoomimage (ellmage, amount.) ( // Разворачивает изображение до указанного размера, var elMap = getMap(ellmage); ellmage.width *= amount; elImage.height *= amount; // Если доступна карта изображения, то она также будет // масштабирована. if (null != elMap) { for {var intLoop = 0; intLoop < elMap.areas.length; intLoop++) { var elArea = elMap.areas[intLoop]; // Разбиение строки координат на массив, var coords = elArea.coords.split(",”); var scaledCoords = // Повторное построение новой масштабированной строки, for (coord in coords) { scaledCoords += (coords(coord) * amount) + } // Помещение масштабированных координат обратно в изображение. elArea.coords = scaledCoords; ) > } function swapButtons(Ы, Ь2) ( // Смена кнопок активизировано/выключено. document, all [Ы] .disabled = true;
Гпава 9. Программирование индивидуальных элементов 251 document.all(Ь2).disabled = false; I </SCRIPT> </HEAD> <BODY> <P> CINPUT TYPE=BUTTON VALUE»"Zoom In" ONCLICK»"zoomimage(document.all.imgl, 2); swapButtons('zoomin’, 'zoomout’);” ID=”zoomin”> CINPUT TYPE=BUTTON VALUE=''Zoom Out" ONCLICK»”zoomimage(document.all.imgl, . 5) ; swapButtons('zoomout', 'zoomin');" ID»"zoomout" DISABLED> c/p> cp> CIMG SRC=”img001.gif" WIDTH=200 HEIGHT=200 ID="imgl" USEMAP="#mapl"> CHAP NAME="mapl”> CAREA SHAPE»"POLYGON" COORDS="92, 140, 126, 114, 155, 139, 124, 163" HREF="home.htm”> CAREA SHAPE»"CIRCLE" COORDS="30, 105, 30” HREF="cool.htm’’> CAREA SHAPE»"RECT" COORDS="62, 28, 200, 79" HREF="dhtml.htm"> </MAP> c/p> • C/BODY> </HTML> Добавление и удаление элементов Area Используя семейство areas, динамический HTML поддерживает способ- ность динамического добавления и удаления элементов Area из карты изо- бражения. При создании нового элемента Area используется тот же метод, что и при создании нового изображения. Главное отличие заключается в том, что новый элемент Area может быть непосредственно добавлен в суще- ствующее семейство all карты, тогда как объект нового изображения не может быть добавлен в документ. Семейство areas представляет методы add и remove. Метод add принимает элемент Area, созданный с помощью метода createEiement, и добавляет его в семейство areas. Метод remove используется для удаления существующего элемента Area из карты изображения. Приведенный ниже пример представ- ляет собой простой редактор карт изображений, написанный целиком на HTML:
252 Часть II. Структура документа <HTML> <HEAD> <TITLE> Редактор карт изображений </TITLE> <SCRIPT LANGUAGE--"JavaScript"> var curFocus = null; function areaFocus() { // Отслеживает последний выбранный элемент Area. if ("AREA" = event.srcEiement.tagName) curFocus = event.srcEiement; } function removeArea() { Il Удаляет элемент Area. var coll = document.all.dynaMap.areas; if (null != curFocus) // Убедитесь, что элемент выбран. II Циклический просмотр элементов Area и поиск выбранного // элемента. for (var intLoop = 0; intLoop < coll.length; intLoop++) if (curFocus == coll[intLoop]) { , document.all.dynaMap.areas.remove(int Loop); return; } alert("No Area element is selected.”); ) function addArea(f) ( /* Убедитесь, что выбраны координаты. Данный код не выполняет дополнительной проверки координат. */ if ("" !- f.coordinates.value) ( var elArea = document.createElement("AREA”); elArea.coords = f.coordinates.value; // Определение выбранной формы. for (var intLoop = 0; intLoop < f.shape.length; intLoop++) if (f.shape[intLoop].checked) elArea.shape = f.shape[intLoop].id; document.all.dynaMap.areas.add(elArea); } else alert("You need to enter a Coords value."); event.returnvalue = false; ) </SCRIPT> </HEAD> <BODY>
Гпава 9. Программирование индивидуальных элементов 253 cHl>Image Map Editorc/Hl> <H2>Select a Shapec/H2> CFORM NAME="area"> с!— Идентификатор ID используется для определения атрибута формы. --> <Р> CINPUT TYPE=RADIO NAME="shape" ID="rect" CHECKED> CLABEL FOR="rect”>Rectc/LABEL> cBR> CINPUT TYPE=RADIO NAME="shape" ID="polygon"> CLABEL FOR="polygon">Polygonc/LABEL> CBR> CINPUT TYPE=RADIO NAME="shape" ID=,,circle"> CLABEL FOR="circle">Circlec/LABEL> c/p> CP> CLABEL FOR="coords“>Coordsc/LABEL> CINPUT TYPE=TEXT ID="coords" NAME="coordinates"> c/P> cp> ' 1 CINPUT TYPE=SUBMIT VALUE="Add Area" ONCLICK=“addArea (this, form) > CINPUT TYPE=BUTTON VALUE=”Remove Area" ONCLICK="removeArea()"> c/P> C/FORM> clMG SRC="img001.gif" WIDTH=200 HEIGHT=200 USEMAP="#dynaMap"> CMAP NAME="dynaMap" ONCLICK="areaFocus()> c/MAP> c/BODY> c/HTML> Программирование элемента Marquee Internet Explorer 3.0 поддерживает простой элемент Marquee (бегущая строка) для горизонтального прокручивания текста. В Internet Explorer 4.0 элемент Marquee был улучшен с помощью полной объектной модели и за счет реали- зации поддержки и воспроизведения любого кода HTML. Новый элемент Marquee может даже содержать элементы управления, которые реагируют на нажатия кнопки мыши и клавиатурный ввод при воспроизведении элемен- та. В число других улучшений входит способность прокручивания в любом направлении — влево, вправо, вверх и вниз. Бегущая строка может отображаться в одном из трех режимов: alternate, scroll и slide. В режиме alternate содержание бегущей строки перемета-
254 Часть II. Структура документа ется вперед и назад, или вверх и вниз, всегда оставаясь на экране. В режи- мах scroll и slide содержание перемещается в одном направлении. Напри- мер, бегущая строка может перемещаться от правой границы экрана к его левой границе. В режиме scroll движение повторяется только после завер- шения прокручивания всего содержания бегущей строки. В режиме slide движение начинает повторяться после вывода па экран последнего элемента содержания бегущей строки. Используя эти три типа поведения, можно оп- ределить конечное число повторений или установить режим повторения до тех пор, пока пользователь не покинет страницу. Свойства анимации бегущей строки Атрибуты бегущей строки представлены как свойства, которые могут быть изменены динамически. Для некоторых из этих свойств назначение нового значения во время выполнения бегущей строки приводит к перезапуску анимации. Изменение других свойств не приводит к такому поведению. В приведенной ниже таблице описаны атрибуты и влияние их изменения на поведение бегущей строки. Таблица 9.2. Атрибуты бегущей строки Атрибут/свойство Перезапускает бегущую строку? Описание behavior Да Определяет режим alternate, scroll или slide для бегущей строки. Значе- ние по умолчанию равно scrol l. direction Нет Определяет направление движения Поддерживаются все четыре направле- ния движения: left, right, up и down. Значение по умолчанию равно right (вправо) height Да Определяет физическую высоту бегу- щей строки loop Да Определяет число повторений анима- ции. Значение по умолчанию равно infinite (бесконечное число раз) scrollAmount Нет Определяет число пикселов перемеще- ния при изменении содержания. Значе- ние по умолчанию равно 6 scrollDelay Нет Определяет число миллисекунд между изменениями содержания. Значение по умолчанию равно 85
Глава 9. Программирование индивидуальных элементов 255 Таблица 9.2 (окончание) Атрибут/свойство Перезапускает бегущую строку? Описание truespeed Нет Определяет, должна ли бегущая строка прерываться при пропущенных циклах. Значение по умолчанию равно false, что определяет поведение бегущей стро- ки как в Internet Explorer 3.0 width Да Определяет физическую ширину бегу- щей строки События бегущей строки Элемент Marquee поддерживает все стандартные события мыши и клавиату- ры. Все элементы, находящиеся внутри бегущей строки, также продолжают запускать соответствующие события. В табл. 9.3 описаны события, которые бегущая строка представляет в ходе анимации. Таблица 9.3. События бегущей строки Событие Описание onstart Бегущая строка скоро начнет прокручиваться. Для бегущей строки в режимах scroll или slide данное событие возникает каждый раз пе- ред запуском последовательности анимации. Для бегущей строки в режиме alternate данное событие возникает один раз в начале ани- мации onbounce Анимация бегущей строки достигла конца и начнется в обратном на- правлении. Данное событие возникает, когда свойство behavior эле- мента Marquee установлено равным alternate onfinish Бегущая строка прекратила прокручивание Методы Marquee Элемент Marquee представляет два метода для запуска и остановки анима- ции: start и stop, которые могут быть использованы для управления про- кручиванием бегущей строки вручную. Используя методы start и stop, приведенный ниже код позволяет пользова- телю останавливать и запускать бегущую строку путем удерживания и от- пускания кнопки мыши над бегущей строкой. Остановив бегущую строку,
256 Часть II. Структура документа пользователю легче прочитать ее содержание. Атрибут title бегущей строки отображается как подсказка (ToolTip), когда указатель мыши удерживается над элементом Marquee. <HTML> <HEAD> <TITLE> Метода stop и start бегущей строки </TITLE> </HEAD> <BODY> <MARQUEE TITLE="Hold down the mouse button to stop the marquee.” ONMOUSEDOWN=”this.stop();" ONMOUSEUP="this.start();"> <Hl>Test Marquec</Hl> <P>Clicking the mouse button and holding it down stops the marquee from scrolling.</P> CINPUT TYPE=BUTTON VALUE=”Demo Button" ONCLICK="alert(1 clicked');"> </MARQUEE> </BODY> </HTML> Программирование элемента Object Элемент object позволяет включать элементы управления и апплеты, кото- рые расширяют возможности браузера. Например, можно создать объекты для внедрения графики или даже других документов непосредственно в до- кумент. Объект может иметь собственные свойства, методы и события, ко- торые элемент object представляет для сценариев так же, как и собственных членов. Обработка конфликтов свойств М. жду членами объекта и членами общего элемента object может возник- нуть конфликт. Например, если объект представляет свойство id, то оно будет конфликтовать со свойством id, представленным элементом object. При возникновении данного конфликта обращение к свойству id указывает версию элемента, а не объекта. Для ссылки на версию объекта свойства id, все элементы объекта представляют свойство object. Данное свойство вос- станавливает доступ к внедренным членам объекта, как показано в приве- денном ниже коде. document.al 1.myObject.id // Свойство id элемента HTML document.all.myObject.object.id // Свойство id внедренного объекта.
Гпава 9. Программирование индивидуальных элементов 257 Альтернативный HTML Элемент object может содержать код HTML, отображаемый браузерами, не поддерживающими элемент object. Содержание низкого уровня представле- но как свойство altHTML элемента object в HTML. Свойство altHTML может быть использовано для передачи содержания поль- зователю, если объект не может быть инсталлирован. Если объект не может быть инсталлирован, то объект на странице заменяется альтернативным со- держанием. В приведенном ниже коде значение свойства altHTML элемента object является элементом Paragraph (теги <р> и </р> между которыми за- ключен текст): <OBJECT CLASSID="java:myClass"> <PARAM NAME="color" VALUE="red"> <P> Ваш браузер не поддерживает элемент Object или возникла ошибка во время загрузки объекта. </Р> </OBJECT> События объекта Объект может генерировать собственные события. Вы можете связать обра- ботчик с таким событием, используя не тег элемента, а синтаксис <script for=event=> или независимый от языка механизм.. Элемент Object пред- ставляет атрибуты только для стандартных событий, а нс для тех, которые генерируются внедренным объектом. Объекты, которые представляют стандартные события, такие как события мыши и клавиатуры, могут также участвовать во всплывании событий. Объект сам может генерировать стандартное событие, после чего браузер запускает это событие во всех родительских элементах. Общие обработчики стандартных событий могут проверить, были ли события генерированы объектом. I Программирование элемента Table Таблицы используются в HTML для отображения табличных данных и для обеспечения большей управляемости расположением элементов в докумен- те. Таблицы состоят из строк. Каждая строка может содержать любое коли- чество ячеек. Динамический HTML представляет индивидуальную модель событий для таблиц, что обеспечивает простой доступ к основным строкам и ячейкам внутри таблицы.
258 Часть II. Структура документа Таблицы были существенно улучшены в Internet Explorer 3.0 для поддержки элементов, которые теперь введены в HTML 4.0. Элементы THead, TBody и TFoot были добавлены для определения разделов заголовка, тела и примеча- ний в таблице. Элементы col и CoiGroup предоставляют большие возможно- сти управления столбцами. При соответствующем использовании данные элементы могут улучшить производительность таблиц, особенно путем оп- ределения ширины столбцов и, обеспечивая большие возможности управле- ния воспроизведением границ. Элемент Table представляет мощную объект- ную модель для динамического манипулирования таблицами. Объект table Каждый элемент Table включает объемную информацию о своем содержа- нии. Объект table обеспечивает доступ к трем различным разделам таблицы: THead, TBody и TFoot. Таблица может содержать по одному элем'енту THead и TFoot, но много элементов TBody. Поэтому объектная модель представляет одиночные свойства tHead И tFoot И СемеЙСТВО tBodies. Объект table представляет методы для создания и удаления элементов THead, TFoot и caption. (На данный момент не существует метода вставки дополнительных элементов TBody в таблицу). Данные методы перечислены в табл. 9.4. Таблица 9.4. Методы объекта table Метод Описание createTHead(), createTFoot(), createCaption() Создает и удаляет определенный раздел, если раздел не существует. Если раздел уже существует, то вместо созда- ния нового, метод возвращает существующий раздел deleteTHead (),, deleteTFoot(), deleteCaption() Удаляет указанный раздел и его строки из таблицы, если раздел существует insertRow([index]) Вставляет строку в таблицу перед строкой номер [index]. Данная строка добавляется в тот же раздел, в котором на- ходится обозначенная индексом index строка. Если значе- ние index не указано, то строка добавляется в конец таб- лицы в том же разделе как последняя строка. Данный ме- тод возвращает строку, которая была вставлена deleteRow(index) Удаляет строку с указанным значением index из таблицы Объект table также использует семейство rows. Данное семейство rows пред- ставляет все строки в таблице, независимо от раздела, в котором находятся строки. Для определения раздела, который содержит строку, вы можете
Гпава 9. Программирование индивидуальных элементов 259 проверить свойство parentEiement отдельной строки. Кроме того, каждый раздел представляет семейство rows, которое содержит содержащиеся в дан- ном разделе строки. Семейства rows и cells Объект table представляет отношения между строками и ячейками таблицы. Как упоминалось выше, семейство rows объекта table содержит все элемен- ты tr в таблице, а семейства rows объектов tHead, tBody и tFoot содержат элементы tr в соответствующих разделах. Каждая строка последовательно представляет семейство cells, которое ссылается на элементы td или тн внутри строки. Семейства rows и cells представляют те же методы tags и item, которые доступны в других семействах элементов. Вы можете исполь- зовать свойство id элемента для непосредственного просмотра семейств rows И cells. Программирование семейства rows Семейство rows в объекте table игнорирует положение строки в заголовке, теле или примечании таблицы, но, тем не менее, поддерживаются отноше- ния элемента tr с родительским элементом: CTABLE ID="myTable"> <THEAD> <TR ID="header"><TH>City</THXTH>State</THX/TR> </THEAD> <TBODY> <TRXTD>Issaquah</TDxTD>Washington</TDX/TR> <TRXTD>Seattle</TDxTD>Washington</TDX/TR> </TBODY> </TABLE> В данном примере семейство rows в объекте шуТаЫе содержит три строки в таблице. Чтобы выяснить, находится ли строка внутри элемента TBody или THead МОЖНО проверить свойство parentEiement отдельной строки: document.all.myTable.rows.length // 3 document.all.myTable.THead.rows.length // 1 document.all.myTable.rows[0].parentEiement.tagName // THEAD documert.all.myTable.rows[1].parentEiement.tagName // TBODY Можно легко определить положение любой строки в таблице. Три свойства строки представляют индекс строки, который начинается с нуля, во всем документе, в таблице п разделе. Свойство sourceindex представляет место- положение элемента в документе. Данное свойство, которое представлено во всех элементах, описано в главе 8.
260 Часть II. Структура документа Свойство rowindex представляет индекс строк во всей таблице, а свойство sectionRowindex представляет индекс строк в своем разделе. В предыдущем примере строка, содержащая Seattle, имеет значение свойства rowindex, равное 2 и значение свойства sectionRowindex, равное 1. (Значение свойства sourceindex строки зависит от местонахождения таблицы в документе). Все строки обеспечивают доступ к своим ячейкам посредством семейства cells. Методы insertcell и deieteCeii добавляют и удаляют ячейки из строки и работают аналогично методам insertRow и deieteRow. Метод insertcell принимает в качестве аргумента необязательный параметр — ин- декс ячейки, перед которой будет вставлена новая ячейка, и возвращает вставленную ячейку. Аргументом метода deieteCeii является индекс удаляе- мой ячейки. Приведенный ниже код показывает, как получить доступ и ма- нипулировать ячейками в приведенной выше таблице: document. all .туТаЫе. rows [0] . cells . length // 2 ячейки document.all.header.cells.length // 2 ячейки, доступ посредством ID document.all.header.deieteCeii(0); // Удаление первой ячейки в строке заголовка. Каждая ячейка имеет свойства sourceindex и celilndex. Свойство ceilindex представляет индекс ячейки в строке. Атрибуты ROWSPAN и COLSPAN Семейство rows соответствует структуре HTML, которая определяет таблицу. Поэтому даже если ячейка охватывает несколько строк, то она представлена только в той строке, которая определяет ячейку. Приведенный ниже код упорядочивает доступ к таблице, которая имеет ряд ячеек, охватывающих множество столбцов и строк: <HTML> <HEAD> <TITLE> Строки и ячейки HTML </TITLE> </HEAD> <BODY> CTABLE BORDER ID="tbll"> <CAPTION>Sample Table</CAPTION> <TRXTD ROWSPAN=3>0, 0</TD> <TD COLSPAN=2>0, l</TDXTD>0, 2</TDX/TR> <TRXTD>1, OC/TDXTD ROWSPAN=2 COLSPAN=2>1, 1</TDX/TR> <TRXTD>2, 0</TDX/TR> </TABLE> <SCRIPT LANGUAGE»"JavaScript"> // Вывод информации о таблице. document.write("<H2>Table Information</H2>");
Глава 9. Программирование индивидуальных элементов 261 with (document.all.tbll) ( for (var intRows=0; intRows < rows.length; intRows++) document.write("Row ” + intRows + ” has ” + rows[intRows].cells.length + " cell(s).<BR>"); document.write(”<P>Here is the same table without " + "any cells spanning multiple rows or columns:"); document.write("<TABLE BORDER>”); for (var intRows = 0; intRows < rows.length; intRows++) { document.write("<TR>"); for (var intCells =0; ' intCells < rows[intRows].cells.length; intCells++) document.write("<TD>" + intRows + + intCells + "</TD>”); document.write("</TR>"); ] document.write("</TABLE>"); ) </SCRIPT> </BODY> </HTML> G 1 HTML Hows end Cells • Miciosoll Interne!... R[*IE31 Sample Table [..[d. 1 Jo. 2; Table Information Row 0 has 3 cell(s). Row 1 has 2 ceH(s) Row 2 has 1 ceU(s) На рис. 9.5 показано отображение данной таблицы в окне браузера. Строки и ячейки определены в основ- ном коде, независимо от действитель- ного воспроизведения таблицы. Числа в ячейках представляют индекс строки в семействе rows, после которого ука- зан индекс этих ячеек в семействе cells. Вторая таблица не имеет атри- бутов ROWSPAN И COLSPAN. COOTBCTCT- вующие ячейки имеют одинаковые индексы в обеих таблицах. Here is the same table without any cells spanning multiple rows or columns •0.0 :0,1; :0 2 j to] ihi] gT i ::: local Htstehww Рис. 9.5. Охватывающие ячейки и содержащие их семейства Вы можете изменить свойства coispan и rowspan для динамического измене- ния схемы размещения таблицы. Изменение данных свойств не приводит к
262 Часть II. Структура документа изменению семейств rows или cells. Единственным способом влияния на семейства является явное добавление или удаление разделов, строк или яче- ек из таблицы при помощи методов вставки и удаления. Событие onresize Событие onresize возникает при изменении размера таблицы. Данное собы- тие генерируется, когда изменяется размер какой-либо ячейки. Сценарий может изменить размер ячейки путем изменения значений свойств height или width или изменения ее содержания. Число ячеек, размер которых из- меняется в ходе одной операции, не имеет значения, поскольку событие onresize возникает только один раз для всей таблицы. Таблицы глобальных стилей В общем случае каскадные таблицы стилей не наследуются содержанием ячейки таблицы. Например, определение элемента font за пределами табли- цы не приводит к тому, что данный шрифт будет использоваться в содержа- нии таблицы. Когда были введены таблицы стилей, данное правило требо- валось выполнять, чтобы гарантировать отсутствие прерываний страниц. Поэтому когда в таблице требуется применить таблицы стилей, они должны быть определены в таблице или ячейках таблицы непосредственно. Это га- рантирует применение таблиц стилей к содержанию таблицы. Создание календаря Приведенный ниже код демонстрирует процедуру манипулирования табли- цей, используя семейства rows и ceils. Сценарий генерирует большинство документов, используя метод document, write. <HTML> <HEAD> <TITLE> Календарь </TITLE> <STYLE TYPE="text/css"> .today (color:navy; font-weight:bold) •days (font-weight:bold) </STYLE> <SCRIPT LANGUAGE="JavaScript"> // Инициализация рядов. var months = new Array("January", "February", "March", "April", "May", "June", "July", "August”, "September", "October", "November", "December"); var daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
Гпава 9. Программирование индивидуальных элементов 263 var days = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"); function getDays(month, year) { , // Проверка, является ли год високосным. if (1 == month) return ((0 == year % 4) && (0 != (year % 100))) || (0 == year % 400) ? 29: 28; else return daysInMonth[month]; } function getTodayt) ( 11 Генерирование сегодняшней даты. this.now = new Date(); this.year = this.now.getYeart) + 1900; // Relative // to 1900 this.month = this.now.getMonth(); this.day = this.now.getDate(); ) // Запуск календаря с сегодняшнего дня. today = new getTodayt); function newCalendar() ( today = new getToday(); var parseYear - parselnt(document.all.year [document.all.year.selectedlndex].text) — 1900; var newCal = new Date(parseYear, document.all.month.selectedlndex, 1); var day - -1; var startDay = newCal. getDay () ; var daily = 0; if ((today.year == newCal.getYear() + 1900) && (today.month -= newCa1.getMonth())) day = today.day; // Кэширование табличного элемента tBody по имени dayList. var tableCal = document.all.calendar.tBodies.dayList; var intDaysInMonth = getDays(newCal.getMonth(), newCal.getYear() + 1900); for (var intWeek = 0; intWeek < tableCal.rows.length; intWeek++) for (var intDay = 0; intDay < tableCal.rows[intWeek].cells.length; intDay++) ( var cell = tableCal.rows[intWeek].cells[intDay];
264 Часть II. Структура документа // Запуск счета дней. if ((intDay =- startDay) && (0 == daily)) daily = 1; // Выделение текущего дня. cell.className » (day == daily) ? "today": // Вывод номера дня в ячейке. if ((daily > 0) &s (daily <= intDaysInMonth)) cell.innerText = daily++; else cell.innerText = } } function getDate() ( // Данный код выполняется, когда пользователь выбирает день в календаре, if ("TD" event.srcElement.tagName) // Test whether day is valid, if ("" != event.srcElement.innerText) alert(event.srcElement.innerText); ) </SCRIPT> </HEAD> <BODY ONLOAD="newCalendar()> <TABLE ID="calendar"> <THEAD> <TR> <TD COLSPAN=7 ALIGN=CENTER> <!— Month combo box —> <SELECT ID="month" ONCHANGE-"newCalender()"> <SCRIPT LANGUAGE»"JavaScript"> // Вывод месяцев в документ. // Выбор текущего месяца. for (var intLoop = 0; intLoop < months.length; intLoop++) document.write("<OPTION " + (today.month ~ intLoop ? "Selected": “’’) + ">” + months[intLoop]); </SCRIPT> </SELECT> <!— Year combo box —> <SELECT ID»"year" ONCHANGE="newCalendar()> <SCRIPT LANGUAGE»"JavaScript">
Гпава 9. Программирование индивидуальных элементов 265 // Вывод лет в документ. // Выбор текущего года. for {var intLoop = 1995; intLoop < 2000; intLoop++) document.write("cOPTION ” + (today.year == intLoop ? "Selected": + ">” + intLoop); </SCRIPT> </SELECT> </TD> </TR> <TR CLASS=”days”> <!— Генерация столбца для каждого дня. —> <SCRIPT LANGUAGE^'JavaScript"> // Вывод дней. for (var intLoop = 0; intLoop < days.length; intLoop++) document.write("<TD>" + days[intLoop] + "</TD>"); </SCRIPT> </TR> </THEAD> <TBODY ID="dayList" ALIGN=CENTER ONCLICK="getDate()"> <!— Генерация сетки для отдельных дней. —> <SCRIPT LANGUAGE^'JavaScript"> for (var intWeeks = 0; intWeeks < 6; intWeeks++) ( document.write("<TR>"); for (var intDays = 0; intDays < days.length; intDays++) document.write("<TD></TD>"); document.write("</TR>"); } </SCRIPT> </TBODY> </TABLE> </BODY> </HTML> Содержание двух раскрывающихся окон со списками, которые указывают месяц и год, генерируется с помощью сценария на основе внутренних мас- сивов, которые отслеживают месяцы и дни календаря. Код также гарантиру- ет, что при загрузке страницы были выбраны текущий месяц и год. Таблица, которая определяет календарь, сама генерируется сценарием, который соз- дает 42 ячейки, используя два вложенных цикла. После загрузки страницы вызывается функция newCalendar, которая автоматически заполняет ячейки элемента tBody таблицы значениями из текущего по календарю месяца.
266 Часть II. Структура документа 11D Calendar * Microsoft Internet Explorer ЯИЕЗ ;i yew go . Fsvooies : .. ИГ (January t| 11998 Sunday Monday Tuesday Wednesday Thursday Friday Saturday 4 5 6 7 1 2 8 9 3 я 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 31 25 26 27 28 29 30 i My J Рис. 9.6. Календарь, созданный с помощью динамического HTML На рис. 9.6 показан пример календаря в окне браузера. В данный пример также включен простой обработчик событий нажатия кнопки, который выполняется при выборе пользователем даты в календаре. На данный момент обработчик только отображает дату, по которой щелкнул пользователь, но он демонстрирует возможности расширения календаря и превращения его в более интерактивное и полезное приложение.
Глава 1 О Формы и внутренние элементы управления В данной главе показано, как программировать пользовательские интерфей- сы, которые запрашивают и обрабатывают вводимую пользователем инфор- мацию. HTML поддерживает элементы управления, которые принимают вводимую пользователем информацию, и элемент, который предоставляет модель формы для группирования содержания и отправки его обратно на сервер. Данные элементы управления называются внутренними элементами управления (intrinsic controls), поскольку они встроены в HTML. Их функ- циональные возможности сильно ограничены при сравнении с большинст- вом пакетов форм и баз данных. Проверка и форматирование еще прямо не поддерживаются, но вы можете легко добавить данные элементы, используя объектную модель. В данной главе представлены методы манипулирования формами и внутренними элементами управления внутри документа. Внут- ренние элементы управления представлены в функциональных категориях, кроме того показаны методы расширения HTML для соответствия возмож- ностям, предоставляемым мощными пакетами форм. В данной главе рассмотрены следующие темы: □ HTML-формы. Формы используются для группирования вводимой поль- зователем информации и отправки ее обратно на сервер. Формы полно- стью доступны для сценариев и таким образом могут быть использованы для обработки на клиентской стороне. В данном разделе представлено введение в формы HTML и элементы input. □ Программирование текстовых элементов input. Текстовые элементы input создают текстовое окно для запроса информации от пользователя. В HTML определены четыре типа текстовых окон: текстовое окно с од- ной строкой, текстовое окно, содержащее множество строк, текстовое окно для ввода пароля и текстовое окно с именем файла. В данном раз- деле внимание сфокусировано на методах использования событий и объ-
268 Часть II. Структура документа ектной модели для проверки и форматирования вводимой пользователем информации. □ Программирование элементов Select (список). Элементы select исполь- зуются для предоставления пользователю определенного набора вариан- тов. С помощью внутренних элементов управления могут быть созданы списки двух типов: поле со списком (list box) и раскрывающееся поле со спи- ском (combo box). Для обоих типов списков используется одна модель программирования. В данном разделе рассмотрены методы программиро- вания списков с помощью сценариев для динамического добавления и удаления элементов списков. □ Программирование списков с помощью кнопок-переключателей и флажков. Альтернативным способом предоставления пользователю возможности выбора из списка элементов является создание набора флажков (check boxes) или кнопок-переключателей (radio buttons). Флажки полезны для простых ответов да/нет. Кнопки-переключатели используются для выбо- ра одного элемента из списка. В данном разделе обсуждаются преимуще- ства использования списков с кнопками по сравнению с использованием окна со списком и объясняются методы написания сценариев. О Программирование элементов командных кнопок. В HTML могут быть созданы четыре типа командных кнопок: текстовые кнопки (plain-text buttons), кнопки в формате HTML (rich HTML buttons), кнопки отправки (submit buttons) и кнопки сброса (reset buttons). Кнопки отправки на сер- вер и кнопки сброса имеют определенную модель поведения, когда поль- зователь находится в формах, и ведут себя как кнопки Default (по умол- чанию) и Cancel (отмена). Кнопка Default отличается наличием дополни- тельной рамки и получает событие нажатия кнопки, когда пользователь нажимает клавишу <Enter>. Кнопка Cancel активизируется в том случае, если пользователь нажимает клавишу <Esc>. Модели поведения команд- ных кнопок других типов должны быть определены с помощью сцена- рия. В данном разделе показано, как использовать преимущества команд- ных кнопок. □ Программирование элементов Label и Fieldset. Надписи (label) и наборы по- лей (fieldset) добавлены в HTML и необходимы для создания форм с форматированием. Элемент Label используется для определения отноше- ний между элементом input и содержанием. Элемент Fieldset использу- ется для определения взаимоотношений между группами элементов управления. HTML-формы Элемент Form используется для логического объединения связанных внут- ренних элементов управления. Данные элементы управления могут при не- обходимости отправлять свои значения обратно на сервер или обрабатывать
Глава 10. Формы и внутренние элементы управления 269 значения непосредственно на машине клиента. При отправке содержания формы указывается имя и значение всех элементов ввода пользователем информации, которые отправляются обратно на сервер. Сервер затем обра- батывает эту информацию и обычно возвращает новую страницу. Приведен- ный ниже HTML-документ демонстрирует форму, которая обрабатывает информацию о пользователе: <HTML> <HEAD> <TITLE> Информация о пользователе </TITLE> </HEAD> <BODY> <FORM NAME- "Userlnfo"> . <LABEL FOR="USER">User Name: </LABEL> CINPUT TYPE-TEXT NAME="USER" VALUE- "User Name" ID="USER"> CLABEL FOR="ADDRESS">Address: </LABEL> cTEXTAREA ROWS-2 COLS-50 NAME-"ADDRESS" ID="ADDRESS"> Enter Address </TEXTAREA> CINPUT TYPE-SUBMIT VALUE- "Submit Information'^ </FORM> </BODY> </HTML> В данном разделе показано, как упаковываются данные для отправки и как можно манипулировать элементом Form и внутренними элементами управ- ления клиента. Обсуждение вопросов реальной обработки формы на сер- верной стороне выходит за рамки данной книги. Область действия форм Каждая форма определяет отдельную область действия для элементов внут- ри формы. Кроме того, каждый элемент за пределами формы использует свою область действия совместно с документом. Определение области дей- ствия элементов input важно, поскольку одна страница может содержать любое число форм, каждая из которых функционирует независимо. Элемент Form не должен находиться внутри других элементов Form, поэтому область действия элемента должна быть очевидна для стороннего пользователя, ко- торый будет просматривать ваш код. Определение области действия разделяет пространство имен, доступных для элементов. Например, если две формы содержат элемент user, то эти эле- менты будут функционировать независимо. Это особенно важно для групп кнопок-переключателей, в которых объединение определяется каждым име- нем элемента. Кнопки-переключатели обеспечивают простой способ демон-
270 Часть II. Структура документа страции разделения областей действия. Например, если две формы на одной странице могут иметь группу кнопок-переключателей state, то кнопки- переключатели будут взаимоисключающими только внутри своих форм. Приведенный ниже документ определяет две раздельные группы кнопок- переключателей, которые совместно используют одно имя: <нтмъ> <HEAD> <TITLE> Демонстрация области действия кнопки-переключателя </TITLE> </HEAD> <BODY> <!— Кнопки-переключатели за пределами формы имеют одну область действия. —> •CINPUT TYPE-RADIO NAME="State“ VALUE=”NJ”>NJ •CINPUT TYPE=RADIO NAME="State" VALUE=”NY">NY •CFORM STYLE="margin-left: 25pt"> <!— Данные две кнопки-переключателя являются взаимоисключающими и независимыми кнопками за пределами данной формы. —> •CINPUT TYPE=RADIO NAME="State" VALUE="WA">WA •CINPUT TYPE=RADIO NAME="State" VALUE="CA">CA </FORM> •CINPUT TYPE=RADIO NAME="State" VALUE="MA">MA </BODY> </HTML> В данном примере все пять кнопок-переключателей совместно используют имя state, но имеют разные области действия. Первые две кнопки- переключателя (NJ, NY) и последняя кнопка-переключатель (МА) находятся внутри одной глобальной области действия и являются взаимоисключаю- щими. Две кнопки-переключателя внутри формы (WA, СА) находятся в об- ласти действия формы и являются взаимоисключающими только друг для друга. Поэтому пользователь может выбрать одно значение из каждой груп- пы кнопок-переключателей. Программирование элемента Form Формы и внутренние элементы управления в пределах области действия имеют богатую модель программирования. С помощью объекта form вы мо- жете отправить и очистить форму, а также получить доступ и манипулиро- вать индивидуальными элементами управления. Семейство forms Формы в документе представлены посредством семейств all и forms. Кроме того, именованные формы имеют специальные отношения с документом и к ним можно обратиться непосредственно как к свойствам самого документа.
Глава 10. Формы и внутренние элементы управления 271 Приведенный ниже код демонстрирует несколько способов обращения к элементам Form с использованием объектной модели. В примечаниях указа- но, что будет отображено в диалоговых окнах Alert. <HTML> <HEAD> <TITLE> Формы в объектной модели </TITLE> </HEAD> <BODY> <FORM NAME=”forml"> </FORM> <FORM NAME=”form2"> </FORM> <SCRIPT LANGUAGE="JavaScript"> alert(document.forms.length) ; // 2 alert(document.forms[0].name); // forml alert (document. forms. form2 .name) ; // form2 alert(document.forml.name); // forml alert(document.all.form2.name); // form2 alert(document.forms["forml”].name); // forml </SCRIPT> </BODY> </HTML> Семейство elements Между формой и се внутренними элементами управления поддерживаются определенные отношения. Все внутренние элементы управления, находя- щиеся внутри формы, представлены посредством свойств объекта form, а также посредством семейства elements, что обеспечивает прямой доступ ко всем внутренним элементам управления, которые существуют в форме. Се- мейство elements объекта form работает аналогично семейству frames объек- та window, в котором семейство представлено просто для повышения легко- сти чтения кода. Как и семейство frames, семейство elements действительно возвращает ссылку на объект form. Например, приведенные ниже две строки кода выполняют одинаковые операции: document.forms(0).length // Число элементов в первой фррме document.forms(0 ] .elements.length Также эквивалентны следующие три ссылки: document.forms(0] document.forms(0 ] .elements document.forms[ 0 ] .elements.elements
272 Часть II. Структура документа Семейство elements работает аналогично другим семействам в объектной модели и обеспечивает доступ к индивидуальным внутренним элементам управления в форме. Семейство elements также содержит все изображения внутри области действия формы. Правила, изложенные в главе 7, могут быть использованы для доступа к со- держанию семейства elements объекта form. Если в форме имеются элемен- ты с одинаковыми именами, то они представлены как подсемейство. Также доступны методы tags и item. Например, приведенный ниже код может быть использован для быстрого доступа ко всем элементам Button в первой форме и для доступа к третьему элементу в данном семействе: // Возвращает семейство кнопок в первой форме. document.forms[01.elements.tags("BUTTON") // Доступ к третьему внутреннему элементу управления в форме, document.forms[01.elements[2] Кром' того, все внутренние элементы управления в форме представляют свойство form, которое возвращает форму, которой они принадлежат. Это полезно, если вам требуется доступ к родительской форме из общего внут- реннего элемента управления для обработчика событий, как показано в приведенном ниже коде: <FORM NAME="User"> <!-- Передает текущую форму обработчику событий. Свойство this обращается к внутреннему элементу управления, а свойство формы обращается к форме, в области действия которой находится элемент управления. —> <INPUT TYPE=TEXT ONCHANGE="doClick(this.form);"> </FORM> ( Примечание Если внутренний элемент управления находится за пределами области дейст- вия формы, то свойство form возвращает null. Передача содержания формы Как упоминалось выше, формы могут быть использованы для обработки данных на клиентской стороне или для отправки данных обратно на сервер. При передаче формы на сервер имя и значение всех элементов формы по- мещаются в одну строку, которая отправляется на сервер. Строка состоит из пар имя-значение, которые разделены амперсандами (&)• Данная строка со- держит имена и значения всех элементов формы, которые имеют имя. На- пример, для формы ввода пользовательской информации в начале данной главы отправляемая строка будет выглядеть следующим образом: * ?USER=SCOTT+ISAACS&ADDRESS=1+Somewhere+Street+WA В данной строке все пробелы заменены на знаки (+).
Гпава 10. Формы и внутренние элементы управления 273 Значения кнопок Кнопки отправляются несколько иным образом, чем стандартные текстовые элементы управления. В табл. Ю.] перечислены правила для различных ти- пов кнопок. Таблица 10.1. Типы кнопок Тип кнопки Описание Кнопка-переключатель В форме отправляется только значение выбранной кноп- ки-переключателя из группы кнопок-переключателей. Если кнопка-переключатель не выбрана, то значение по умолчанию равно ON Флажок Флажки отправляют свои пары имя-значение только когда они выбраны. Если флажок не указан, то значение по умолчанию равно on Submit (Отправить) В форме может быть указано несколько кнопок Submit. Если кнопке Submit назначено имя, то ее пара имя- значение отправляется вместе с формой Имена разделяемых элементов Правила определения содержания отправляемой формы просты: внутренний элемент управления должен иметь имя и должны быть выбраны кнопки. Поскольку в группе кнопок-переключателей может быть выбрана одновре- менно только одна кнопка-переключатель, то для каждой группы кнопок- переключателей отправляется только одно значение. Однако нс требуется, чтобы имена в отправляемой строке были уникальными. Например, если имена ряда флажков совпадают, то будут отправлены пары имя-значение всех выбранных флажков с данным именем. И в полях со списками, допус- кающими выбор нескольких вариантов (multiple-select list box) (в дальней- шем мы будет называть их поля со списками для множественного выбора) пара имя-значение отправляется для каждого выбранного элемента. Кнопки отправки также подчиняются этим правилам. Однако поскольку одновременно может быть выбрана только одна командная кнопка, то от- правляется информация о нажатии кнопки Submit. С помощью данного ме- тода можно отличить несколько кнопок Submit в одной форме друг от друга. В большинстве случаев, однако, отправка значения для кнопки Submit не- обязательна и кнопке не требуется назначать имя. Отключенные элементы и элементы только для чтения Элементы могут быть отключены с помощью Сценария или HTML. Отклю- ченные элементы (disabled elements) не могут получать фокус и отображаются серым цветом в окне браузера Microsoft Internet Explorer. Поскольку отклю-
27<l Часгь II. Структура документа чснный элемент не учитывается в текущем контексте формы, то его значе- ние опускается при отправке формы. Содержание элементов только для чтения (read-only elements) не может быть изменено. По умолчанию кнопки предназначены только для чтения, а все остальные внутренние элементы управления можно изменять. Хотя отсутст- вует возможность изменения кнопки, можно установить запрет на модифи- кацию других внутренних элементов управления, используя атрибут readonly языка HTML или соответствующее свойство объектной модели. В отличие от отключенных элементов, элементы только для чтения отправ- ляются вместе с содержанием формы. Значения элемента Object Браузер Internet Explorer 4.0 поддерживает отправку элемента object (объект) вместе с формой, если объект имеет имя и значение но умолчанию, которое может быть отправлено. Это позволяет отправлять апплеты и эле- менты управления ActiveX так же, как и другие внутренние элементы управ- ления. Куда отправляется содержание формы? По умолчанию отправляемая строка перелается обратно на сервер с теку- щим адресом URL. Для отправки данных можно использовать два метода: get и post. Используемый метод определяется в свойстве формы method. По умолчанию установлен метод get, который обеспечивает присоединение от- правляемой строки к адресу URL. Полученная в результате строка открыва- ется как новый якорь. Выбор используемого метода отправки зависит от того, какое приложение запущено на сервере. Вместо отправки формы обратно по адресу URL страницы можно устано- вить индивидуальное местоположение для формы, используя свойство action формы. Свойство action содержит адрес URL программы сервера, которая принимает отправленные формой данные. Данное свойство может динамически изменяться для приема данных в разных точках. Куда возвращаются результаты формы? В то время как свойство action определяет место на сервере для приема данных, свойство get определяет место на клиентской машине, где будет храниться возвращаемая информация. Свойство target работает аналогично свойству target элемента Anchor и используется для определения окна или фрейма, в котором будет отображаться содержание. Данное свойство может быть использовано для создания пользовательского интерфейса, в котором постоянно обновляется не вся область экрана. Например, отображаются два фрейма, один из которых может запрашивать ввод информации пользовате- лем, а другой может отображать возвращаемый результат.
Гпава 10. Формы и внутренние элементы управления 275 Отмена отправки формы Для динамической отправки или предотвращения отправки формы могут быть использованы сценарии. Вы можете воспрепятствовать отправке фор- мы путем возвращения значения false в обработчик событий onsubmit. Для этого следует установить значение false для свойства returnvalue объекта event или возвратить false непосредственно событию. Общая ошибка при возвращении значения обработчику событий заключается в возвращении значения только в строку кода в обработчике событий, а не в обработчик событий непосредственно, как показано ниже: <HTML> <НЕАГ» <TITLE> Отмена отправки формы — неправильный способ </TITLE> CSCRIPT LANGUAGE»"JavaScript"> function doSubmit(f) ( return false; ) </SCRIPT> </HEAD> CBODY> <!— Отправка формы не отменена. —> CFORM ONSUBMIT»"doSubmit(this);”> CINPUT TYPE=CHECKBOX NAME="Info"> CINPUT TYPE=SUBMIT> c/FORM> c/BODY> </HTML> В данном примере отправка формы не отменяется, хотя значение false воз- вращается вызванной функцией, поскольку возвращаемое значение потом не передается в обработчик событий onsubmit. Правильным способом отмены отправки формы является возвращение зна- чения, которое вернула вызванная функция. Ниже показано, как определить тег cform>: CFORM ONSUBMIT="return doSubmit(this);"> Теперь, когда выполняется обработчик событий onsubmit, значение, возвра- щаемое функцией, корректно передается в обработчик событий. Отправка формы Метод submit объекта form обеспечивает отправку данных формы. Вызов метода submit не запускает события onsubmit. Поэтому если необходима проверка, то обработчик событий onsubmit должен быть вызван вручную,
276 Часть II. Структура документа перед вызовом метода отправки method, как показано в приведенном ниже коде. При использовании данного метода возвращаемое обработчиком со- бытий onsubmit значение всегда следует проверять. <HTML> <НЕАГ» <TITLE> Отправка формы вручную </TITLE> <SCRIPT LANGUAGE^'JavaScript"> function doSubmit(f) ( // Код условия, который определяет, будет ли произведена отправка return f.Info.checked; } function manualSubmit(f) { var isSubmit = f.onsubmit(); // Отправка, если нс возвращается никакого значения или // значения true. if ((isSubmit) II (null==isSubmit)) f.submit(); // Отправка формы. > </SCRIPT> С/НЕАГ» <BODY> <FORM ONSUBMIT="return doSubmit(this) // Должно быть возвращено значение обработчика событий."> CINPUT TYPECHECKBOX NAME=”Info"> CINPUT TYPE=BUTTON ONCLICK="manualSubmit(this.form)" VALUE="Submit"> C/FORM> C/BODY> </HTML> Сброс содержания формы При первой загрузке страницы исходные установки элементов управления сохраняются в специальных свойствах по умолчанию. Для текстовых эле- ментов управления свойством по умолчанию является defaultvalue. Для ко- мандных кнопок или кнопок-переключателей свойством по умолчанию яв- ляется свойство defaultchecked, для элементов списков свойством по умол- чанию для каждого элемента является defaultselected. При сбросе содержания формы значения данных свойств копируются обратно в значе- ния элементов управления. Кнопка Reset обеспечивает выполнение встроенного метода для сброса со- держания формы к исходным значениям. Аналогичное действие может быть
Глава 10. Формы и внутренние элементы управления 277 промоделировано в форме путем вызова метода reset в самой форме. По- добно методу submit формы событие onreset не возникает, когда вызывается метод reset. Прием, продемонстрированный в предыдущем разделе для ме- тода submit, может быть также использован для запуска метода reset после первого вызова обработчика событий onreset. Надо ли использовать элемент Form? Элемент Form необходим, когда ожидается, что пользователь отправит ре- зультаты на сервер. С помощью динамического HTML элементы управления могут быть использованы исключительно для взаимодействия на клиентской стороне. В данном случае элемент Form необязателен и элементы управления могут быть непосредственно внедрены па страницу. Использование элемента Form для манипуляций на клиентской стороне не оказывает отрицательного воздействия и предоставляет ряд преимуществ. Использование элемента Form обеспечивает группирование элементов input внутри семейства elements и выделение пространства имен для кнопок- переключателей. Кроме того, в Netscape Navigator элементы управления отображаются и доступны из сценариев, только если они содержатся внутри блока формы. Если требуется обеспечить совместимость с Netscape Navigator, то элементы управления всегда должны находиться внутри эле- мента Form. Скрытие и отображение внутренних элементов управления Динамический HTML поддерживает специальный тип внутренних элемен- тов управления, которые всегда скрыты. Поскольку пользователь может об- ращаться к данному элементу и манипулировать им, то данный элемент преимущественно используется в качестве места для рассчитанной величи- ны, которая должна быть отправлена вместе с формой. Элемент input неви- дим, если значение его атрибута type равно hidden. Поэтому если необходи- мо динамически изменять режим вывода элемента на экран, то следует ис- пользовать стандартный внутренний элемент управления и установить для его свойства display в CSS значение попе или значение hidden для свойства visibility. Впоследствии, изменив значение свойств visibility или display, можно вывести элемент управления на экран. Подобно элементу input со значением hidden, невидимые внутренние элементы управления отправляются вместе с содержанием формы. Приведенный ниже код делает невидимый в исходном состоянии элемент видимым. Если внутренний эле- мент управления являлся элементом input со значением hidden, то свойство display не оказывает на него влияния.
278 Часть If, Структура документа <INPUT TYPE=TEXT STYLE="display:none" ID="myTextbox"> <SCRIPT LANGUAGE="JavaScript"> // Отображение текстового окна. document.all.myTextbox.style.display = </SCRIPT> Использование элементов Input co значением HIDDEN Элементы input hidden наиболее полезны для передачи рассчитанных дан- ных вместе с формой. С помощью элементов input hidden можно обойти недостаток браузера Netscape Navigator, который обусловливает повторную инициализацию переменных в сценариях при каждом изменении размеров окна. Вы можете сохранить переменные в скрытых полях и не волноваться об изменении пользователем размеров окна. Спрятанное поле представляет ту же объектную модель, что и текстовое окно без событий, связанных с пользовательскими действиями. Взаимодействие с отключенными внутренними элементами управления Отключенные элементы отображаются серым цветом. Однако если отклю- ченное текстовое окно содержит текст, то пользователю нелегко определить, что данный элемент является отключенным. Проверив, взаимодействует ли пользователь с отключенным элементом управления с помощью всплывания событий, вы можете обеспечить вывод объяснения для пользователей, когда они попытаются щелкнуть по отключенному элементу управления. Отключенные элементы управления не генерируют события. Напротив, со- бытия генерируются на первом активизированном родительском элементе. Приведенный ниже код демонстрирует добавление специального сообщения "disabledError" для внутреннего элемента управления и затем проводит его общую проверку: <HTML> <HEAD> <TITLE> Демонстрация отключенных элементов </TITLE> <SCRIPT LANGUAGE-”JavaScript"> function checkcontrol() { /* Если пользователь щелкает по отключенному элементу управления, то данный код отображает сообщение об ошибке, если оно существует.*/ var el = event.srcElement; if (el.disabled) ( var msg = el.getAttribute("disabledError"); if (null != msg) alert(msg);
Глава 10. Формы и внутренние элементы управления 279 else alert("You clicked on a disabled element."); } } • </SCRIPT> </HEAD> <BODY ONCLICK="checkControl()"> <INPUT TYPE=BUTTON DISABLED VALUE="Demo" disabledError = "This element is disabled because..."> </BODY> </HTML> ( Примечание В ранних проектах HTML был предложен атрибут ERROR для внутренних эле- ментов управления. Не следует добавлять индивидуальный атрибут е; г or для гарантии отсутствия конфликтов, если данный атрибут станет частью рекомен- даций HTML в будущем. Программирование текстовых элементов Input В HTML поддерживаются перечисленные ниже четыре типа текстовых эле- ментов управления для запроса информации у пользователя: □ <INPUT TYPE=TEXT> □ CINPUT TYPE=PASSWORD> □ CINPUT TYPE=FILE> □ <TEXTAREA>...</TEXTAREA> Элемент input text создает текстовое окно с одной строкой, а элемент TextArea создает текстовое окно со множеством строк. Элемент input password представляет текстовое окно с одной строкой, в которой вводимые пользователем символы отображаются в виде звездочек (*). Элемент inpul file отображает текстовое окно и кнопку, с помощью которой пользователь может выбрать локальный файл. При отправке формы содержание выбран- ного файла отправляется обратно на сервер. ( Примечание Элемент TextArea, так же как и любой другой элемент, который отображает полосы прокрутки в динамическом HTML, представляет свойства scrollTop, scrollLeft, scrollWidth и scrollHeight4Данные свойства обеспечивают полный набор возможностей для изменения размера вывода на экран содер- жания документа. Более подробную информацию о данных четырех свойствах можно найти в главе 9.
280 Часть II. Структура документа Различные текстовые элементы input в HTML на данный момент не имеют встроенных возможностей по проверке и форматированию пользователь- ского ввода. До появления сценариев эти функциональные возможности приходилось реализовывать на сервере, что часто приводило к росту трафи- ка между сервером и клиентом. С помощью сценариев на клиентской сто- роне и возможностей динамического HTML вы можете форматировать и проверять вводимую пользователем информацию мгновенно на стороне клиента. В данном разделе внимание сосредоточено на проверке введенной пользователем информации. Доступ к содержанию элемента управления Содержание текстовых элементов input представлено с помощью свойства value или innerText для прямого доступа к содержанию как строке и метола createTcxtRange для расширенного доступа к символам, словам или предло- жениям содержания. Свойство innerText является псевдонимом свойства value. Данные свойства используются взаимозаменяемо. Манипулирование текстом с помощью объекта TextRange обсуждается в главе 14. В данной главе внимание обращено на использование свойства value для манипулирова- ния содержанием элемента управления. Элемент загрузки файлов Тег <input type=file> позволяет загружать на сервер содержание файла, имя которого указано в текстовом окне. По соображениям безопасности элемент File Upload (Загрузка файлов) имеет ограниченную объектную модель. Эле- мент File upload поддерживается в Netscape Navigator версий 3.0 и более поздних и в Internet Explorer 3.02 и более поздних версиях. Свойство value данного элемента предназначено только для чтения и содержит имя файла и путь, а не содержание файла. В элементе File upload поддерживаются собы- тия, но их использование сильно ограничено, так как вы не можете мани- пулировать введенной пользователем информацией. При необходимости можно использовать данные события и свойство value, чтобы проверить, был ли выбран файл. Проверка введенной пользователем информации Проверка информации, введенной пользователем, до ее обработки повыша- ет эффективность использования Web-узла. В данном разделе представлены четыре метода, которые могут быть использованы с любым текстом, введен- ным пользователем.
Глава 10. Формы и внутренние элементы управления 281 Проверка во время ввода пользователем текста Проверка каждого вводимого пользователем символа может выполняться путем отслеживания событий клавиатуры: keypress, keydown и keyup. Собы- тие keypress является самым полезным событием для отслеживания ввода с клавиатуры, поскольку действие по умолчанию события keypress заключает- ся в обработке вводимого символа. Возврат значения false в данное собы- тие препятствует обработке символа, поэтому символ не будет присоединен к введенной пользователем информации. Приведенный ниже пример иллю- стрирует установку ограничения для ввода в текстовом окне только число- вой информации. <HTML> ! CHEAD> <TITLE> Проверка во время набора пользователем текста </TITLE> c/HEAD> <BODY> CLABEL FOR="age”>Agec/LABEL> CINPUT ID=”age" TYPE=TEXT SIZE=3 ONKEYPRESS="if ((event.keyCode C 48) |I (event.keyCode >57)) event.returnValue = false;”> c/BODY> </HTML> В данном текстовом окне можно вводить только значения ASCII в диапазо- не от 48 до 57, которые представляют цифры на клавиатуре от 0 до 9. Любые другие символы, введенные пользователем, будут проигнорированы. Проверка после выхода пользователя из элемента управления Немедленная проверка наиболее полезна для фильтрации вводимых пользо- вателем данных. Более общим подходом является проверка введенной поль- зователем информации после окончания ввода. При вводе недействитель- ных значений будет выведено уведомление с использованием одного из двух следующих методов: □ Изменение внешнего вида элемента для указания недействительных зна- чений. □ Вывод окна с просьбой исправить недействительное значение, когда пользователь покидает поле. . . Оба метода используют событие onchange, которое запускается в момент вы- хода пользователя из внутреннего элемента по'сле изменения значения. Со- бытие onchange генерируется для данного элемента непосредственно перед событием onblur. Оно может быть использовано для проверки введенных
282 Часть II. Структура документа пользователем данных и затем для отображения диалогового окна или изме- нения внешнего вида формы на основе ввода. Отмена события onchange за- прещает пользователю выход из элемента управления при навигации на данной странице. Если пользователь переходит на другую страницу, то от- мена данного события не отменяет возможности перехода. Приведенный ниже код демонстрирует изменение стиля элемента на основе введенного значения. Данный метод подробно описан в главе 11. Динамическое изменение стиля полезно для обеспечения ясной обратной связи с пользователем. <HTML> <HEAD> <TITLE> Проверка при выходе из элемента управления — метод 1 </TITLE> cSTYLE TYPE="text/css"> .badValue (background:red; color:white} </STYLE> CSCRIPT LANGUAGE^'JavaScript"> function validateNumber() ( // Получение исходного элемента. var el = event.srcElement; // Valid numbers var num = "0123456789"; event.returnValue = true; /* Циклическая проверка содержания. Если обнаруживается символ, не являющийся числом, то возвращается значение false. */ for (var intLoop = 0; intLoop < el.value.length; intLoop++) if (-1 == num.indexOf(el. value, char At.(intLoop))) event.returnValue=false; if ((event.returnValue) // Неправильное значение el.className = "badValue"; // Изменение класса, else // Сброс класса для использования воспроизведения по умолчанию, el.className=""; ) •c/SCRIPT> </HEAD> <BODY> cLABEL FOR="Age">Age:</LABEL> CINPUT ID="Age" TYPE=TEXT SIZE=3 TITLE="Enter your age" ONCHANGE="validateNumber();"> </BODY> c/HTML> Вместо изменения стиля элемента вы можете предупредить пользователя с помощью диалогового окна Alert о том, что введено недействительное зна-
Глава 10. Формы и внутренние элементы управления 283 чение. Приведенный ниже код демонстрирует вывод предупреждение, если пользователь вводит недействительное значение в поле State. Кроме того, данный код демонстрирует выполнение элементарного форматирования, переводя введенные пользователем символы в верхний регистр. <HTML> <HEAD> <TITLE> Проверка при выходе из элемента управления — метод 2</TITLE> <SCRIPT LANGUAGE="JavaScript"> function checkstate(check) ( var states = "ALAKAZARCACOCTDEDCFLGAHIIDILINIAKS"; states += "KYLAMEMDMAMIMSMNMOM'TNENMNVNHNJNMNY"; states += "NCNDOHOKORPARISCSDTNTXUTVTVAWAWVWIWY"; // Приведенный ниже код проверяет ввод провинций Канады. /* Провинции Канады добавляются только в случае, если указан второй параметр, значение которого равно true. */ if (arguments[1]) states += "ABBCMBNBNFNSONPEPQSK"; /* Если строка не обнаружена в четной позиции, то ытат является недействительным. */ return (0 == (states.indexOf(check) % 2)); } </SCRIPT> </HEAD> <BODY> CLABEL FOR="state">State:</LABEL> <INPUT ID="state" TYPE=TEXT SIZE=2 MAXLENGTH-2 ONCHANGE="this.value = this.value.toUpperCase(); if (!checkstate(this.value))( alert('Invalid State'); return false;}”> </BODY> </HTML> Проверка при отправке формы Можно использовать проверку при отправке данных формы, чтобы выясне- нить, является ли связанная информация действительной или для обеспече- ния передачи всей запрашиваемой информации. Например, если пользова- тель указывает, что он состоит в браке, то может также потребоваться ввести имя супруга (или супруги). Приведенный ниже код демонстрирует расши- рение текстового окна с помощью атрибута required гарантирующего его заполнение пользователем: <HTML> <HEAD>
284 Часть II. Структура документа <TITLE> Проверка при отправке пользователем формы </TITLE> cSCRIPT LANGUAGE="JavaScript"> function isEmpty(str) ( // Проверка, является ли строка пустой. for (var intLoop = 0; intLoop < str.length; intLoop++) if (” ” != str.charAt(intLoop)) return f al sex- return true; } function checkRequired(f) { var strError = for (var intLoop = 0; intLoopcf.elements.length; intLoop++) if (null!=f.elements[intLoop].getAttribute("required")) if (isEmpty(f.elements[intLoop].value)) strError += " " + f.elements[intLoop].name + ”\n"; if ("" != strError) ( alert("Required data is missing:\n" + strError); return false; } } C/SCRIPT> </HEAD> CBODY> CFORM NAME="demo" ONSUBMIT="retum checkRequired(this);"> User Name: <INPUT TYPE=TEXT NAME="User Name" required><BR> E-Mail Address: CINPUT TYPE=TEXT NAME=”E-Mail Address" required><BR> Age (optional): CINPUT TYPE=TEXT NAME="Age"XBR> CINPUT TYPE=SUBMIT VALUE="Submit"> c/FORM> C/BODY> C/HTML> Представление требуемой информации Расширение приведенного выше примера, которое продемонстрировано в приведенном ниже коде, заключается в использовании для отображения за- полняемых полей другого цвета фона. При вводе пользователем информа- ции в этих полях цвет фона изменяется на цвет по умолчанию, что помогает пользователю определить поля, которые следует заполнить перед отправкой формы. cHTML> CHEAD>
Глава 10. Формы и внутренние элементы управления 285 <TITLE> Представление требуемой информации </TITLE> <STYLE TYPE="text/css"> .required (background: red} </STYLE> <SCRIPT LANGUAGE="JavaScript"> function isEmpty(str) ( for (var intLoop = 0; intLoop<str.length; intLoop++) if (" " != str.charAt(intLoop)) return false; return true; function checkRequired(f) ( for (var intLoop = 0; intLoop<f.elements.length; intLoop++) if ("required"==f.elements(intLoop].className) { alert(”All red fields are required."); return false; ) } function fixUp(el) { el.className = isEmpty(el.value) ? "required”: ) function checkChar(el) ( if (32 != event.keyCode) el.className = </SCRIPT> </HEAD> <BODY> <FORM NAME="demo" ONSUBMIT="return checkRequired(this) ; "> User Name: <INPUT TYPE=TEXT CLASS=”required” ONKEYPRESS=”checkChar(this);” ONCHANGE="fixUp(this);"><BR> E-Mail Address: <INPUT TYPE=TEXT CLASS="required" ONKEYPRESS="checkChar(this) ONCHANGE="fixUp(this);"><BR> Age (optional): <INPUT TYPE=TEXT SIZE=3><BR> <INPUT TYPE=SUBMIT VALUE="Submit"> </FORM> </BODY> </HTML>
286 Часть II. Структура документа В данном примере для идентификации необходимых полей вместо опреде- ляемого пользователем атрибута required используется атрибут class. Форматирование введенной пользователем информации Путем вывода предупреждений можно научить пользователя вводить дан- ные, а форматирование вводимой пользователем информации помогает представить данные в более удобном для чтения и использования виде. Те же методы, которые были использованы для проверки данных, могут быть использованы и для их форматирования. Форматирование введенной поль- зователем информации может осуществляться на стадии набора символов, или когда пользователь покидает поле ввода. В данном разделе показано расширение встроенных внутренних элементов управления для добавления информации форматирования непосредственно в элемент с использованием двух индивидуальных атрибутов. Приведенный ниже код содержит минимально необходимое число инструк- ций, в число которых входит подпрограмма проверки числовых данных, ко- торая использовалась ранее, и простая программа форматирования для из- менения стиля, если число является положительным или отрицательным. Хотя в данном примере показано только изменение стиля, но может быть написана программа форматирования, которая будет производить индивиду- альное форматирование значения — например, путем добавления числовых разделителей или других элементов индивидуального формата. <HTML> <HEAD> <TITLE> Форматирование введенной пользователем информации </TITLE> <STYLE TYPE="text/css"> .positive {color:green) .negative {color:red) .badValue {background:red; color:white) </STYLE> <SCRIPT LANGUAGE="JavaScript”> function formatNumber() { with (event.srcElement) className = parseint{value) >= 0 ? "positive": "negative"; ) function validateNumber() { // Получение-исходного элемента. var el = event.srcElement; var num = "0123456789"; // Valid numbers event.returnValue = true;
Глава 10. Формы и внутренние элементы управления 287 // Проверка знака первого символа. event.returnvalue = == el.value.charAt(0)) II (-1 != num.indexOf(el.value.charAt(0))); /* Циклическая проверка остального содержания. Если обнаруживается символ, который не является числом, то возвращается значение false. */ for (var intLoop = 1; intLoop < el.value.length; intLoop++) if (-1 = num.indexOf(el.value.charAt(intLoop))) event.returnValue = false; if (!event.returnValue) . // Bad value el.className = "badValue"; // Change class, else // Очистка класса для использования воспроизведения по умолчанию, el.className = } function checkFormat.O ( event.returnValue = true; , if (null !- event.srcEiement.validate) if ("number" == event.srcEiement.validate) validateNumber(); // Sets event.returnValue if ((null != event.srcEiement.getAttribute("format”)) && (event.returnValue)) if ("number" == event.srcEiement.getAttribute("format")) formatNumber(); </SCRIPT> </HEAD> <BODY> <INPUT TYPE=TEXT ONCHANGE="checkFormat();” format="number" validate="number"> </BODY> </HTML> Использование элементов ввода пароля Поле Password представляет собой текстовое поле, в котором вводимые пользователем символы отображаются в виде звездочек. Эта мера безопас- ности полезна, когда пользователь вводит важную информацию. По сообра- жениям безопасности сценарии, выполняющиеся в Internet Explorer 4.0, не могут обращаться к действительным значения^ элемента управления. Вме- сто этого свойство value всегда возвращает знак * для всех вводимых поль- зователем символов. Звездочки помогают клиентской программе проверить,
288 Часть II. Структура документа что был введен пароль и что пароль имеет определенное число символов Связанные с нажатием клавиш события также всегда возвращают символ звездочка (*). При использовании полей Password для передачи данных следует применять метод post. В противном случае значение пароля будет отображаться как значение search в отправляемой форме. В любом случае значение не шиф- руется. Более того, Netscape Navigator в настоящее время отображает реаль- ное введенное значение, а не звездочки, так что поля Password следует ис- пользовать аккуратно. Программирование элементов списков Элемент select, используется для предоставления пользователю списка ва- риантов. Существуют два типа списков: раскрывающееся паче со списком (combo box) и поле со списком (list box). Данные два типа списков взаимоза- меняемы и их модели сценариев идентичны. Единственным исключением является то, что стиль поля со списком может быть использован для созда- ния поля со списком для множественного выбора, что позволяет пользова- телю выбирать элементы из нескольких полей со списками. На рис. 10.1 показаны три типа списков. Q Litt Types -Microsoft Internet Емркме* ННЕЗ | i file View go fjelp Combo Вок (Computer M Multiple-Select List Box Moil Oidei Рис. 10.1. При использовании элемента select доступны три типа списков Определение поля со списком Для создания поля со списком используется элемент Select. Элемент Select содержит элементы Options, представляющие каждый элемент списка. Могут быть созданы три типа полей со списками, как показано в приведенном ниже коде: <HTML> <HEAD>
Глава 10. Формы и внутренние элементы управления 289 <TITLE> Типы списков </TITLE> </HEAD> <BODY> <FORM NAME="lists"> <SELECT NAME="cornbostore"> COPTION VALUE=''Computer" SELECTED>Computer</OPTION> cOPTION VALUE="Bookstore”>Book Store</OPTION> cOPTION VALUE="MailOrder">Mail Order</OPTION> </SELECT> cSELECT NAME="liststore" SIZE=3> COPTION VALUE="Computer" SELECTED>Computer</OPTION> cOPTION VALUE="Bookstore">Book Storec/OPTION> COPTION VALUE="MailOrder”>Mail Orderc/OPTION> С/SELECT> cSELECT NAME="multistore" SIZE=3 MULTIPLE> cOPTION VALUE="Computer" SELECTED>ComputerC/OPTION> . cOPTION VALUE="Bookstore">Book Store</OPTION> COPTION VALUE="MailOrder" SELECTED>Mail Orderc/OPTION> c/SELECT> c/FORM> </BODY> </HTML> Определение атрибута приводит к образованию поля со списком вместо раскрывающегося поля со списком. Значение атрибута size определяет чис- ло отображаемых строк. Для создания нескольких полей со списками следу- ет определить атрибут multiple. Если атрибут multiple указан без атрибута size, то автоматически создается поле со списком, содержащее четыре строки. Добавление стилей в поле со списком Для поля со списком предоставляется ограниченная таблица стилей. Цвет текста и фона для каждого варианта может быть изменен с помощью табли- цы стилей, что позволяет создавать внешне привлекательные окна со спи- сками или даже селектором цветов: <HTML> <HEAD> <TITLE> Селектор цветов </TITLE> </HEAD> <BODY> cSELECT STYLE="width:75pt"> <OPTION STYLE="background:red; colorrwhite" VALUE="RED"> Red </OPTION>
290 Часть II. Структура документа <OPTION STYLE="background:navy; color:white“ VALUE="NAVY"> Navy </OPTION> <OPTION STYLE="background:black; color:white" VALUE="BLACK"> Black </OPTION> <OPTION STYLE="background:white; color:black" VALUE="WHITE"> White </OPTION> </SELECT> </BODY> </HTML> Стиль для выбранных элементов в списке в данном примере не изменяется. Связь списка с отправляемым значением Содержание элемента option отображается на экране, но это отображаемое значение не отправляется обратно на сервер. Вместо этого значения отправ- ляется атрибут value, который должен быть определен в теге <optlon>. В общем, при использовании элемента Select внутри отправляемой формы каждый вариант должен иметь атрибут value. Для списков, которые манипулируются сценарием и не отображаются на экране, может быть ис- пользован атрибут value, или сценарии могут непосредственно учитывать значение свойства text. Программирование содержания списка Семейство options представляет элементы Option, содержащиеся в элементе Select. Каждый вариант в данном семействе представляет свои атрибугы, а также содержание, ограниченное открывающими и закрывающими тегами элемента Option, которые представлены с помощью свойства text. Элементы Option Элементы Option в документе являются исключением в объектной модели динамического HTML, поскольку они не представлены в семействе all до- кумента. Кроме того, элемент Option не предоставляет никаких дополни- тельных событий или свойств помимо стандартного набора атрибутов и свойства text. Элемент option представлен только родительским элементом Select, владеющим всеми взаимодействиями со списком, включая события. Добавление и удаление элементов списка Вы можете динамически добавлять или удалять* элементы из поля списка. Данный метод позволяет настраивать список в ответ на ввод информации пользователем.
Глава 10. Формы и внутренние элементы управления 291 Для добавления или удаления значении из поля списка можно использовать метод, вве- денный в главе 9 для добавления или удаления областей на карте изображения. В дан- ном разделе представлен более подходящий для этой цели метод. Семейство options поддерживает способность динамического добавления или удаления элементов. Элементы создаются с использованием метода createEiement или с помощью оператора new, как показано ниже: var elOption = createEiement("OPTION"); // or var elOption = new Option; // Netscape Navigator поддерживает данный метод. Затем варианты добавляются в поле со списком при помощи метода add в семействе options или удаляются с помощью метода remove. Варианты могут быть добавлены или удалены путем назначения варианта непосредственно индексу массива или путем установки существующего параметра, равным null. Данный метод поддерживается для совместимости с Netscape Navigator. Приведенный ниже код сравнивает использование данных мето- дов в поле со списком 1b в форме с именем demo: var elOption = new Option(); // Add and remove using methods. document.demo.lb.options.add(elOption, 0); // Добавляет первый элемент, document.demo.lb.options.remove(2); // Удаляет третий элемент. // Добавление и удаление с использованием метода, совместимого // с Netscape Navigator. document.demo.lb.options[0] = tslOption; // Добавляет первый элемент, document.demo.lb.options(2) = null; // Удаляет третий элемент. Приведенный ниже код демонстрирует динамическую генерацию поля со списком, которое содержит все закладки па странице. Когда пользователь выбирает элемент из списка, документ автомагически отображает выбран- ную закладку. <HTML> <HEAD> <TITLE> Список закладок </TITLE> <SCRIPT LANGUAGE»"JavaScript"> function addNew(text, value) { // Добавляет новый вариант. var el = document.createEiement("OPTION"); el.text = text; el.value = value; document.all. tan.options.add(el); }
292 Часть II. Структура документа function buildListO ( /* При добавлении нового элемента списка текст является содержанием якоря, а значением является имя закладки. Значение используется для прокручивания элемента в окне. 1! for (var intLoop - 0; intLoop < document.anchors.length; intLoop++) addNew(document.anchors{intLoop].innerText, document.anchors[intLoop].name); ) function scrollit(where) ( // Прокручивает выбранную закладку в области просмотра, document, all [where, value] . scroll IntoView () // Сброс поля co списком, where.value - null; } ’ </SCRIPT> </HEAD> «BODY ONLOAD="buildList() ; "> «LABEL ГОК=’’Ьт">Вооктагкз: «SELECT TD=bm STYLE="width:lOOpt” ONCHANGE^'scrollit(this);’’> </SELECT> «Н1ХА NAME="Contents">Contents</AXHl> Table of Contents <H2>«A NAME="Abstract">Abstract«/Ax/H2> About this document <H2><A NAME="Chapterl">Chapter 1«/Ax/H2> Chapter 1 <H2><A NAME="Summary">Summary</A>«/H2> Summary contents </BODY> </HTML> Программирование множественного выбора в поле со списком Поле со списком, допускающее множественный выбор (multiple-select list box), позволяет пользователю выбрать более одного элемента. В поле со списком с множественным выбором свойство V3.J-UG ВОЗНЁЙЩЯСТ ТОЛЬКО ПСр" вый выбранный элемент. Для определения всех выбранных элементов дол- жен быть перечислен весь список элементов с помощью сценария. Приве- денная ниже функция демонстрирует построение массива из элементов, ко- торые выбраны из поля со списком. (При исйЬльзовании данной функции для поля со списком с одиночным выбором полученный в результате массив будет содержать только одно значение).
Глава 10. Формы и внутренние элементы управления 293 <SCRIPT LANGUAGE""JavaScript"> function getSelected(opt) { var selected = new ArrayO; var index =0; for (var intLoop=0; intLoop < opt.length; intLoop-t-t) { if (opt[intLoop].selected) { index = selected.length; selected[index] = new Object; selected[index].value = opt[intLoop].value; selected[index].index = intLoop; } } return selected; ) </SCRIPT> Использование флажков для небольших списков Если число вариантов в списке невелико, то может оказаться разумнее ис- пользовать набор флажков вместо поля со списком с множественным выбо- ром. Путем совместного использования одного имени для всех флажков в наборе для флажков может быть установлена модель отправки, аналогичная модели поля со списком с множественным выбором. Приведенная выше функция может быть переписана, как показано в следующем коде, для оп- ределения выбранных флажков. Вместо перечисления элементов семейства options, находящихся в элементе select, вы должны перечислить элементы Form с данным именем. Вместо передачи семейства options функции ис- пользуется семейство флажков. Еще одним отличием является то, что флаж- ки представляют свойство checked для определения, были ли они выбраны, в то время как поле со списком использует свойство selected. Поэтому ус- ловие В функции проверяет свойства selected И checked. <HTML> <HEAD> <TITLE> Поле co списком для множественного выбора </TITLE> <SCRIPT LANGUAGE""JavaScript"> function getSelected(opt) { var selected = new ArrayO; var index = 0; for (var intLoop - 0; intLoop < opt.length; intLoopt+) ( if [(opt[intLoop].selected) II (opt[intLoop].checked)) ( index = selected.length; selected[index] - new Object; selected[index].value - opt[intLoop].value;
294 Часть II. Структура документа selected[index].index = intLoop; } } return selected; } function outputSelected(opt) { var sei = getSelected(opt); var strSel = for (var item in sei} strSel += sei[item].value + "\n”; alert("Selected Items:\n" + strSel); } </SCRIPT> </HEAD> <BODY> <FORM NAME="ColorSelector"> CINPUT TYPECHECKBOX NAME="color" VALUE="Red">Red CINPUT TYPECHECKBOX NAME="color" VALUE="Navy" CHECKED>Navy CINPUT TYPECHECKBOX NAME="color" VALUE="Black">Black CINPUT TYPECHECKBOX NAME=”color” VALUE="White" CHECKED>White CINPUT TYPE=BUTTON VALUE=”Selected Check Box Items" ONCLICK="outputSelected(this.form.color);”> <P> cSELECT NAME="multistore" SIZE=3 MULTIPLE> cOPTION VALUE="Computer" SELECTED>Computer</OPTION> OPTION VALUE="Bookstore">Book Store</OPTION> OPTION VALUE-"Mailorder" SELECTED>Mail Order</OPTION> </SELECT> CINPUT TYPE=BUTTON VALUE="Selected List Items" ONCLICK“"outputSelected(this.form.multistore.options)"> </FORM> </BODY> </HTML> Программирование списков с использованием кнопок-переключателей и флажков Кнопки-переключатели и флажки воспроизводятся аналогично, но служат разным целям. Кнопки-переключатели используются для представления на- бора из двух или более взаимоисключающих вариантов. Флажки использу- ются для выбора решения с учетом двух или большего количества независи- мых установок.
Глава 10. Формы и внутренние элементы управления 295 Кнопки-переключатели сходны с полем со списком для одиночного выбора, которое было рассмотрено выше в данной главе. Кнопки-переключатели могут быть использованы взаимозаменяемо с полем со списком для одиноч- ного выбора, но наиболее эффективны при наличии небольшого числа ва- риантов. Например, для указания поля пользователя группа кнопок- переключателей может быть более эффективна, чем ноле со списком для одиночного выбора. Кнопки-переключатели сложнее в использовании, чем поле со списком, если вы создаете набор вариантов в динамическом режиме. Для данной схе- мы лучше подходит поле со списком, поскольку элементами в поле со спи- ском можно легко манипулировать как группой, тогда как каждая кнопка- переключатель в действительности представляет собой отдельный элемент управления, которым следует манипулировать независимо, и добавление или удаление кнопок-переключателей требует непосредственного манипу- лирования содержанием документа. Кнопки-переключатели Кнопки-переключатели (radio buttons) представлены как группа, подобно ва- риантам в окне со списком для одиночного выбора. Как упоминалось выше, определение одного имени для кнопок внутри одной области действия при- водит к созданию группы. Взаимное исключение на основе имени поддер- живается только для кнопок-переключателей. При отправке формы с груп- пой кнопок-переключателей отправляется только значение выбранной кнопки-переключателя. Назначение того же имени любому другому типу элементов управления не приводит к появлению специального поведения при отправке. Когда элементы управления, которые нс являются кнопками- переключателями, совместно используют одно имя, то все пары имя- значение отправляются соответствующим образом, в зависимости от правил для каждого элемента управления — например, отправляются только вы- бранные именованные флажки и все именованные текстовые окна. Поддержка пользовательских элементов списка Кнопки-переключатели полезны для предоставления возможных ответов при проведении опросов. Иногда возникает необходимость предоставить возможность пользователю самому дать ответ на вопрос, если не подходят все указанные варианты ответа. Приведенный ниже код демонстрирует про- стой способ создания текстового окна для индивидуальных ответов, если пользователь не нашел подходящего варианта среди предложенных. Тексто- вый элемент управления активизируется только после выбора параметра Other (Другие). <HTML> <HEAD>
296 Часть II. Структура документа <TITLE> Индивидуальный ввод </TITLE> <SCRIPT lALIGUAGE^" JavaScript "> function checkRadio(f) ( f.Custom.disabled = If.QI["Other"].checked; if ("Other" == event.srcElement.id) f.Custom.focus <); ) ’ . </SCRIPT> </HEAD> <BODY> <FORM NAME="Demo" ONCLICK="checkRadio(this);"> <FIELDSET> <LEGEND>Where did you buy this book?</LEGENt)> <PXINPUT ID=”BStore" TYPE=RADIO NWE="Q1" VALUE="Bookstore"> <LABEL FOR="BStore"> Bookstore</LABEL> kPXINPUT ID="MOrder" TYPE=RADIO NAME="Q1” VALUE="Mail Order"> <LABEL FOR="MOrder"> Mail Order</LABEL> <PXINPUT ID="CStore" TYPE=RADIO NAMF^"Q1" VALUE="Comp Store"> <LABEL FOR=”CStore"> Computer Store</LABEL> <PXINPUT ID="Other" TYPE=RADIO NAME="Q1"> <LABEL FOR=”Other"> Other: </LABEL> <INPUT ID="Custom" NAME="Other" TYPE=TEXT DISABLED> </FIELDSET> </FORM> </BODY> </HTML> Данный код работает правильно независимо от того, щелкнет ли пользова- тель по надписи Other или самой кнопке-пере ключа гелю, поскольку когда пользователь щелкает по надписи, то сначала генерируется событие onclick с элементом srcElement в качестве надписи и затем данное событие генери- руется снова с элементом srcElement в качестве кнопки-переключателя. Об- работчик событий onclick также запускается, если выбрана кнопка- переключатель с помощью клавиатуры, поскольку событие связано не с мышью, а с операцией изменения значения элемента управления. По дан- ной причине одного обработчика событий onclick для кнопки- переключателя достаточно для отслеживания любых возможных изменений. Флажки Флажки (check boxes) полезны для создания вопросов, на которые требуется простой ответ типа да/нст. Во многих случаях текстовые поля используются при необходимости определения дополнительной информации. Создав про-
Гпава 10. Формы и внутренние элементы управления 297 стой код, вы можете сделать установку флажка условием активизации опре- деленных полей в форме. В приведенном ниже коде, если пользователи за- прашивают дополнительную информацию, то они должны ввести имя и ад- рес электронной почты. Если дополнительная информация не запрашивает- ся, то эти поля не используются. <HTML> <HEAD> <TITLE> Активизация полей ввода </TITLE> </HEAD> <BODY> <FORM NAME="Info"> CLABEL FOR=INFO>Send Info:</LABEL> CINPUT ID=INFO TYPECHECKBOX ONCLICK=this.form.email.disabled - ! this.shecked; this.form.snailMail.disabled -!this.checked;"> <BR> CFIELDSET NAME="address" > <LEGEND>Address Informat ion</LEGEND> CLABEL FOR="email">E-Mail Address:c/LABEL> CINPUT TYPE=TEXT NAME="email" DISABLED > CLABEL FOR="snailMail">Street Address:c/LABEL> CTEXTAREA ROWS=3 COLS=40 NAME="snailMail" DISABLEDX/TEXTAREA> </FIELDSET> C/FORM> </BODY> </HTML> ( Примечание j На данный момент отсутствует метод для изменения воспроизведения по умолчанию отключенных элементов управления. Состояние неопределенности Флажки поддерживают состояние неопределенности, что позволяет флаж- кам находиться в одном из трех состояний: включено (оп), выключено (off) и неопределенное (unknown). Предположим, что вы используете флажок, чтобы выяснить, набран ли выбранный текст шрифтом с полужирным начертани- ем. Неопределенное состояние возникнет, когда часть выбранного текста будет набрана полужирным шрифтом, а другая часть — обычным шрифтом. Состояние неопределенности может быть установлено только посредством объектной модели, используя свойство indeterminate для флажка. Свойство indeterminate представляет собой логическое значение — если свойство имеет значение true, то флажок будет отображен в неопределенном состоянии.
298 Часть II. Структура документа Свойство checked неопределенного флажка возвращает значение флажка до его перехода в неопределенное состояние. Даже если неопределенный фла- жок всегда остается неизменным в пользовательском интерфейсе. Значение флажка отправляется в зависимости от значения его свойства checked, неза- висимо от того, находится ли флажок в неопределенном состоянии или нет. На рис. 10.2 показаны флажки в различных состояниях. Г" Not Checked Р! Checked P Indeterminate R Not Checked Disabled I? Checked and Disabled Рис. 10.2. Возможные состояния флажков Флажок в неопределенном состоянии выглядит так же, как выбранный и отключенный флажок. Разница заключается в том, что вы не можете щелк- нуть по отключенному флажку для изменения его значения, но можете вы- брать неопределенный флажок. Событие onclick Для кнопок-переключателей и флажков событие onclick ведет себя не- сколько по-иному, чем для других элементов. Событие onclick запускается до выполнения действия по умолчанию, что дает Web-автору возможность его отмены. Для флажков действие по умолчанию заключается в выборе или отключении элемента, а для кнопок-переключателей действие по умолча- нию заключается в выборе элемента. Когда событие onclick генерируется для этих событий, то значение элемента управления уже представляет новое значение для элемента. Отмена действия по умолчанию приводит к актуали- зации предыдущего значения. Данный процесс отличен для других элемен- тов, состояние которых не изменяется до возникновения события. Программирование элементов командных кнопок Командные кнопки создаются с использованием стандартного элемента input или элемента Button. Элемент input поддерживает три типа команд- ных кнопок: отправка, сброс и просто текст. Элемент Button является но- вым элементом в Internet Explorer 4.0 и обеспечивает способность создания элементов с форматированием HTML.
Глава 10. Формы и внутренние элементы управления 299 Определение кнопок по умолчанию и отмены Кнопки отправки и сброса ведут себя как кнопки Default (По умолчанию) и Cancel (Отмена) в контексте формы или области действия документа. Кноп- ка Default первоначально отображается с дополнительной рамкой вокруг нее и определяет действие по умолчанию, которое возникает при нажатии поль- зователем клавиши <Enter>. Кнопка Cancel определяет действие, происхо- дящее при нажатии пользователем клавиши <Esc>. Внутри области действия формы кнопки отправки и сброса представляют собой командные кнопки, для которых установлено определенное поведе- ние отправки или сброса содержания формы. За пределами формы данные кнопки ведут себя как стандартные командные кнопки Default и Cancel. Во всех случаях вызов модели поведения кнопки Default или Cancel с помощью клавиатуры запускает событие click в соответствующем элементе кнопки. Кнопки отправки и сброса определены с помощью атрибута type элемента input или Button, как показано ниже: <FORM NAME="User"> <INPUT TYPE=TEXT NAME="User" VALUE="User Name"> CINPUT TYPE=RESET VALUE="Reset the Form"> CINPUT TYPE=SUBMIT VALUE=”Submit the Form"> CBUTTON TYPE=SUBMITXEM>Submit</EM> the Formc/BUTTON> </FORM> В форме или области действия документа может быть только одна кнопка Default и одна кнопка Cancel. Если в некоторой области действия определе- но несколько кнопок Default или Cancel (то есть, более одной кнопки от- правки или сброса), то в данной области будет использована первая опреде- ленная в коде HTML кнопка каждого типа. События кнопок и форм Если требуется код, который будет выполняться для моделей поведения от- правки или сброса формы, то следует написать код для событий onsubmit и onreset формы, но не события onclick кнопок отправки и сброса, посколь- ку форма может быть случайно отправлена или сброшена без получения кнопкой события onclick. Например, если форма имеет одно текстовое ок- но, кнопку отправки и кнопку сброса, то нажатие клавиши <Enter>, пока курсор находится в текстовом окне, автоматически отправляет значение, но кнопка отправки не получает событие onclick* Аналогично, если пользова- тель нажимает клавишу <Esc>, то кнопка сброса не получает события onclick, но генерируется событие onreset.
300 Часть II. Структура документа Создание кнопок при помощи элемента Button Вы можете создать кнопку в коде HTML, используя тег cinput type-button> или более общие теги <виттоы> ... </button>. Приведенный ниже код соз- дает кнопки отправки и сброса с надписями: CFORM NAME=”test"> CBUTTON TYPE=SUBMIT> <Hl>Submit this form.</Hl> </BUTTON> CBUTTON TYPE=RESET> cH2>Reset this form.c/H2> c/BUTTON> </FORM> Поместив HTML в элемент Button, можно создать интересные эффекты для кнопки. Хотя код HTML и стиль могут быть определены для содержания, но модель событий ограничена в сравнении с остальной частью динамиче- ского HTML. События кнопки Как показано в приведенном ниже коде, элемент Button поддерживает фор- матирование HTML, но элементы внутри кнопки нс генерируют события Поэтому нельзя написать обработчики событий для элементов, которые су- ществуют внутри кнопки. <!— Обработчики событий, которые определены в данной кнопке, не запускаются. —> <BUTTON> <Н1 ONCLICK=''alert ('clicked! 1); ">Click Ме!</Н1> СН2 ONMOUSEOVER="this.style.color = 'red';”>Turn red.</H2> c/BUTTON> Напротив, все события элементов внутри элемента Button направляются не- посредственно кнопке. Содержание кнопки Содержание кнопки представлено различно в зависимости от того, с помо- щью каких тегов определена кнопка: тега cinput> или cbutton>. Содержание кнопки, созданной с помощью тега <input>, представлено свойствами value и innerText, аналогично другим типам input. Содержание кнопки, создан- ной с помощью тега cbutton>, представлено свойствами innerText. и innerHTML, а не свойством value. Подобно элементу TextArea кнопка, соз- данная с помощью тега <button>, также предоставляет расширенный доступ К содержанию с ПОМОЩЬЮ метода createTextRange.
Гпава 10. Формы и внутренние элементы управления 301 Программирование элементов Label и Fieldset Надписи используются для связи содержания HTML с элементом input, а наборы полей применяются для группирования нескольких элементов управления. Элементы Label и Fieldset в настоящее время поддерживаются только браузером Internet Explorer 4.0. Элемент Fieldset полезен при труп пировании различных элементов ввода пользователем в одной форме — например, для группирования адресов от- правки и получения в одной форме. Элемент Fieldset не имеет дополни- тельных элементов в объектной модели кроме стандартных событий и их атрибутов. Однако совместно с процедурой всплывания событий элементы Fieldset могут быть использованы для обеспечения индивидуального пове- дения групп элементов управления. Элементы i^bel особенно удобны для использования вместе с флажками и кнопками-переключателями. До появления элементов Label для выбора кнопки-переключателя или флажка следовало выполнить щелчок непосред- ственно по выбираемому элементу. Теперь для выбора или снятия выделе- ния кнопки можно также щелкнуть по связанной с кнопкой надписи. Пре- имущество использования элементов Label заключается в том, что они обеспечивают выделение элементов управления рамкой, наглядно представ- ляя их содержание и создавая дополнительную область нажатия, которая может быть использована для выбора элемента управления. Данный элемент может быть добавлен без какого-либо риска на любую Web-страницу, так как браузеры низкого уровня игнорируют элемент Label. Элемент Label и события onclick Элемент Label оказывает интересное влияние на модель событий. Действие по умолчанию при щелчке по элементу Label заключается в том, что свя- занный элемент управления получает фокус. Поэтому, когда пользователь щелкает по элементу Label, этот элемент и все его родительские элементы получают событие onclick. Если действие по умолчанию не отменяется, то указанный элемент управления получает фокус. Если указанный элемент является флажком или кнопкой-переключателем, то событие onclick затем всплывает снова из этого элемента управления. Второе всплывание дает возможность щелкать по надписи кнопки-переключателя или флажка для изменения значения элемента. Если не требуется различать щелчки по надписи и самому элементу управ- ления, то присоедините обработчик событпу к элементу управления, а не к надписи.

Стиль документа и анимация Глава 11. Динамические стили Глава 12. Динамическое позиционирование

r"a»»11 J Динамические стили Динамические стили являются интегральным компонентом интерактивных Web-страниц. Вид документа определяется с помощью таблиц стилей и HTML. Динамические стили используют объектную модель для модифика- ции каскадных таблиц стилей документа (CSS) с целью внесения изменений во внешний вид документа. Синтаксис описания CSS был введен в главе /. В данной главе внимание сосредоточено на вопросах изменения таблиц стилей с помощью сценариев для изменения внешнего вида документа. Применяя динамические стили, вы можете улучшить внешний вид имею- щихся документов без потери содержания в браузерах низкого уровня. В браузере низкого уровня документ будет отображаться в статическом ре- жиме, а в браузерах с поддержкой динамического HTML документ оживет. Поскольку самым простым и наиболее эффективным способом изучения динамических стилей является рассмотрение и анализ примеров кода, то в данной главе представлено большое число программных модулей, которые можно использовать по принципу Plug and Play (вставь и работай). Целью данных примеров является демонстрация применения различных методов для создания более интерактивных документов. В данной главе рассмотрены следующие темы: □ Динамические стили и CSS. В этом разделе вводятся взаимоотношения между CSS и динамическими стилями. Сравниваются отношения между динамическими стилями, применимыми к CSS, и процедурным языком таблиц стилей, таким как JavaScript Accessible Style Sheets (JASS), кото- рый включен в Netscape Navigator 4.0. □ Свойства таблиц стилей. В данном разделе*описано, как свойства таблиц стилей представлены посредством объектной модели. Свойства CSS не всегда легко конвертируются в свойства объектной модели, поскольку
206 Часть III. Стиль документа и анимация одиночный атрибут может содержать множество свойств. Например, ат- рибут background содержит цвет фона, изображение и повторяющуюся информацию. □ Внутренние стили. В этом разделе показаны приемы программирования внутреннего стиля элемента, что является простейшим методом добавле- ния динамических стилен. Свойство style, которое обеспечивает доступ ко всем связанным с CSS свойствам, представлено для всех элементов. □ Изменение атрибута class. Простым и элегантным способом создания динамических стилей является написание кода, который модифицирует атрибут class или id для связи элемента с другим контекстуальным пра- вилом. В этом разделе представлены доступные для повторного исполь- зования примеры, которые иллюстрируют данный метод. □ Таблицы глобальных стилей. Изменение внутреннего стиля и атрибута class является прямым изменением элемента. Объект document представ- ляет семейство stylesheets, которое содержит все элементы style и таб- лицы связанных стилей в документе. Данное семейство позволяет моди- фицировать индивидуальные таблицы стилей непосредственно, и, таким образом, применять форматирование ко всему документу. □ Методы. В конце данной главы приведены три раздела, которые демон- стрируют методы использования преимуществ элементов, рассматривав- шихся на протяжении всей книги. В разделе "Адаптивные методы размещения" разъясняется, как обеспечить изменение документа в соответствии с определенной средой. В разделе "Методы отображения данных"рассматривается скрытие и отображение данных в ответ на действия пользо- вателя. В разделе "Методы анимации текста" описаны методы изменения стиля в за- висимости от таймера. Примеры, демонстрирующие использование данных методов, находятся на прилагаемом компакт-диске. Динамические стили и CSS CSS определяет режим воспроизведения отдельных элементов в документе. Объектная модель манипулирования свойствами таблицы стилей основана на рекомендациях CSS. Когда атрибут или правило изменяются посредством сценария, то статическая таблица стилей и страница обновляются. Данная модель динамических стилей отличается от модели JASS, поддержи- ваемой в Netscape Navigator 4.0. JASS является процедурной моделью опре- деления таблицы стилей документа во время его анализа, а не моделью программирования для манипулирования стилем документа. Например, JASS может быть использована для написания кода условия, который при- меним к различным таблицам стилей в зависимости от размера экрана в хо-
Гпава 11. Динамические стили 307 де загрузки документа. JASS не может быть использован для изменения сти- ля элемента в ответ на событие без перезагрузки или запроса новой страни- цы с сервера. В Microsoft Internet Explorer 4.0 динамические стили не являются процедур- ным языком таблиц стилей, но они могут реализовать все аспекты JASS и предоставляют дополнительные возможности. Вместо определения альтер- нативного языка таблиц стилей, динамические стили в internet Explorer 4.0 модифицируют таблицу стилей документа, определенную CSS, путем пре- доставления возможности определения внутренних свойств style для всех элементов, включения и отключения таблиц внутренних и глобальных сти- лей, добавления и изменения правил для существующей таблицы стилей. Свойства таблиц стилей Таблицы стилей (style sheets) представляют ряд свойств, которые управляют внешним видом содержания элемента. В объектной модели данные свойства представлены с использованием соглашения об именовании. Большинство свойств в CSS разделяют ключевые слова при помощи дефиса (-). Посколь- ку дефис интерпретируется как оператор в большинстве языковых конст- рукций, он не может быть частью имени свойства CSS, которое представле- но в объектной модели. Более того, для чувствительных к регистру языков, гаких как JavaScript, все представленные свойства CSS согласованы с другими свойствами — то есть, первый символ набран в нижнем регистре, а все последующие ключевые слова выделены прописными буквами. Например, свойство каскадных таблиц стилей margin-top представлено в объектной модели как marginTop. ( Примечание ) Хотя это простое правило и может применяться в общем случае, но существует одно исключение, которое необходимо для предотвращения конфликта с дру- гими языками написания сценариев. Свойство float в CSS определяет вырав- нивание элемента по левому или правому краю, так что окружающий текст бу- дет обтекать данный элемент. Поскольку float является распространенным типом данных во многих языках программирования, то свойство float каскад- ной таблицы стилей представлено в объектной модели как styleFloat. Составные свойства Многие свойства таблиц стилей определены как составные свойства. На- пример, атрибут каскадных таблиц стилей background содержит информа- цию о фоновом изображении, URL, положении и так далее. Приведенный ниже фрагмент кода содержит атрибут background, определенный для эле- мента Body: body {background:red URL(cool.gif)}
зоа Часть ///. Стиль документа и анимация Иногда составными свойствами трудно манипулировать с помощью сцена- рия. Для программирования свойства background разработчику пришлось бы разложить свойство CSS на составляющие компоненты. Такой анализ уп- рощен в объектной модели CSS разложением составных свойств CSS на не- сколько свойств, каждое из которых представляет определенный аспект со- ставного. В табл. 11.1 перечислены индивидуальные свойства составного свойства background. Таблица 11.1. Компоненты составного свойства background Свойство Описание backgroundcolor Название цвета или значение RGB backgroundimage Адрес URL фонового изображения backgroundposition Положение фонового изображения backgroundRepeat Определяет повторение фонового изображения по горизонта- ли, вертикали или по обоим направлениям backgroundscroll Определяет, прокручивается ли фоновое изображение вместе с документом или представляет статический водяной знак Свойство cssText Свойство cssText содержит стиль элемента в форме или строке. Используя данное свойство можете установить стиль элемента или скопировать стиль из одного документа в другой. Приведенный ниже код назначает параграфу р2 стиль, который был установлен в параграфе pi. Раздел данной главы "Создатель таблиц стилей" содержит подробный пример определе- ния и совместного использования правил стилей во всем документе. <HTML> <HEAD> <TITLE> Совместное использование свойства cssText </TITLE> </HEAD> . <BODY> cP ID="pl” STYLE="text-indent:.5in; color:red"> Параграф красного цвета с отступом в полдюйма. с/Р> cP ID="p2"> Данный параграф имеет внешний вид по умолчанию. Нажмите CINPUT TYPE=BUTTON VALUE="здесь" ONCLICK="document.all.p2.style.cssText. = document.all.pl.style.cssText;”>
Глава 11. Динамические стили 309 для того чтобы данный параграф выглядел как первый параграф. </Р> </BODY> </HTML> Изменение свойств Большая часть свойств таблиц стилей, поддерживаемых браузером Internet Explorer 4.0, может быть изменена динамически, но некоторые свойства нельзя изменить в динамическом режиме: □ Для свойства display можно установить значение попе или значение по умолчанию. Поэтому элементы нс могут переключаться между формата- ми блока и внутренним форматом. Установка значения, отличного от попе или значения по умолчанию, ‘отображает содержание документа с использованием значения по умолчанию. □ Свойство styieFloat не является полностью динамическим для текстовых элементов, таких как span и div. Для текстовых элементов свойство styieFloat может принимать только значения left и right. Если тексто- вый элемент не был изначально выровнен по левому или правому краю, то выравнивание не может быть установлено после загрузки докумен- та. Для элементов ввода (select, Button, input и так далее) свойство styieFloat может динамически принимать любое действительное значение. □ Свойство position доступно только для чтения и не может быть динами- чески изменено для элементов. Внутренние стили Внутренний стиль (inline style) назначается элементу с помощью атрибута style. Атрибут style позволяет назначать свойства CSS непосредственно экземпляру элемента. Например, используя элемент style можно установить цвет параграфа: < Р STYLE»"color:Ыие">Это параграф голубого цвета.</Р> До таблиц стилей цвет параграфа можно было установить, используя эле- мент Font: <PxF0NT COLOR="Blue”> Это параграф голубого цвета.- </FONTx/P> Преимущества использования внутреннего стиля по сравнению со стилевы- ми элементами и атрибутами HTML перечислены ниже: □ Создает более компактный код HTML □ Позволяет уменьшить дерево анализа, что повышает производительность □ Обеспечивает лучшее разделение концепций стиля и структуры
310 Часть III. Стиль документа и анимаций Даже внутренние стили не следуют в точности духу разделения представле- ния и содержания. Истинное отделение представления от содержания за- ключается в определении всех стилей за пределами разметки — для этой цели наиболее уместны таблицы глобальных и внутренних стилей. Таблица внутреннего стиля обеспечивает некоторые возможности для соз- дания динамических документов. Например, стиль документа может быть легко изменен при проведении через него указателя мыши: <Н1 ONMOUSEOVER="this.style.backgroundcolor = 'yellow';" ONMOUSEOUT="this.style.backgroundcolor = ''; Элемент становится желтым, когда над ним проходит указатель мыши. </Н1> Данный код получает доступ к внутреннему стилю для элемента ill и уста- навливает повое значение для свойства backgroundColor. Документ немед- ленно обновляется, отражая изменения в таблице стилей. Внутренний стиль представлен для всех элементов свойством style. Свойство style имеет зна- чение объекта, посредством которого сценарии могут обращаться ко всем свойствам CSS. Изменение атрибута class Изменение внутреннего стиля полезно, но это может оказаться тяжелой за- дачей, если необходимо модифицировать значения сразу нескольких свойств. Более эффективным способом является изменение стилей для од- ного или большего количества классов в таблице глобальных стилей и ди- намическое изменение атрибута class элемента. Атрибут class элемента представлен свойством classNtime. Данное свойство может быть изменено с помощью сценария для связи другого правила стиля с элементом. Напри- мер, приведенный ниже код перезаписывает метод изменения цвета onmouseover из предыдущего раздела с учетом преимуществ таблиц глобаль- ных стилей: <HTML> <HEAD> <TITLE> Изменение атрибута class </TITLE> <!— Создание таблицы глобальных стилей. —> <STYLE TYPE="text/css"> .yellow (background:yellow; font-weight:bolder) </STYLE> </HEAD> <BODY> <H1 ONMOUSEOVER=''this. className = 'yellow';" ONMOUSEOUT=”this. className = "; ”>
Глава 11. Динамические стили 311 Атрибуты класса данного элемента изменяются при перемещении над ним указателя мыши. </Н1> </BODY> </HTML> В данном примере значение атрибута class изменяется на yellow (желтый), когда указатель мыши перемещается через элемент hi. Это приводит к не- медленному применению стиля, определенного для значения yellow. В этом случае фон становится желтым, а текст выделяется полужирным начертани- ем. Метод изменения имен класса имеет два преимущества: □ Одна строка кода может изменить несколько частей стиля □ Изменение таблицы стилей вместо изменения кода может привести к изменению самого эффекта Данный метод особенно полезен при необходимости получения стандарт- ного эффекта для нескольких элементов сразу. Можно установить динамические элементы управления, используя тот же метод. Код в приведенном ниже примере изменяет таблицу стилей, связан- ных с кнопкой, в ответ на четыре события мыши: перемещение указателя мыши через элемент и снятие указателя мыши с элемента, нажатие и отпус- кание левой кнопки мыши. <HTML> <HEAD> <TITLE> Анимированные кнопки </TITLE> CSTYLE TYPE="text/css"> .over (color:yellow; background:navy) .down (color:yellow; background:navy; font-style:italic) </STYLE> </HEAD> <BODY> CINPUT TYPE=BUTTON VALUE=”Demo Button" ONMOUSEOVER="this.className = 'over';" ONMOUSEOUT="this.className = " ;" ONMOUSEDOWN="this.className = 'down•;" ONMOUSEUP="this.className = 'over';”> </BODY> </HTML> Данный пример может быть также применен к другим событиям и другим элементам и переписан в общем виде путем помещения обработчиков собы- тий в элемент Body. Если указать для кнопки в предыдущем примере новый стиль по умолчанию путем назначения ему имени класса, то придется соблюдать осторожность
312 Часть III, Стиль документа и анимация при повторном назначении имени класса в ответ на событие onmouseout. Код в следующем примере автоматически отслеживает имена исходного класса элементов. Пример демонстрирует повторно используемую архитек- туру для назначения различных эффектов onmouseover различным элемен- там, включая вложенные элементы с небольшим количеством кода для каж- дого элемента. <HTML> <HEAD> <TITLE> Эффекты "взрыва" </TITLE> <STYLE TYPE="text/css"> .explode {coloured; letter-spacing:5px) .header {color:green) /* Для установки эффекта просто определите новые правила и свяжите их с элементами документа. */ </STYLE> CSCRIPT LANGUAGE="JavaScript"> function walkstyles(src) { /* Просмотр дерева; для каждого элемента со свойством эффекта заменяет значения его свойств эффекта и className. Просмотр дерева необходим, чтобы гарантировать обработку всех вложенных эффектов. */ while ("HTML” != src.tagName) { if (null != src.getAttribute("effect", false)) ( var tempClass = src.className; src.className = src.getAttribute("effect", false); src.setAttribute("effect", tempClass, false); } src = src.parentElement; ) ) function setupEffect() { // Обращение к элементу walkStyles(event.toElement); ) function cleanupEffect(} { // Выход из элемента walkstyles(event.fromElement); ) // Связывает обработчики событий. document.onmouseover = setupEffect; document. onmouseout = cleanupEffect; </SCRIPT> </HEAD>
Глава 11. Динамические стили 313 <BODY> <Н1 CLASS="header" effect="explode"> Данный элемент "взрывается" при проведении над ним указателя мыши. </Н1> </BODY> </HTML> В приведенном выше коде элемент Н1 имеет определенный пользователем атрибут effect, содержащий имя класса, которое будет использовано при нахождении указателя мыши над элементом. Когда указатель мыши нахо- дится над элементом, то функция walkstyles меняет значения свойств className и effect элемента, изменяя их стиль. Когда указатель мыши по- кидает элемент, данная функция производит обратную замену значений. Вы можете легко добавить новые элементы с собственными эффектами в данный код. Необходимо просто определить новые классы в таблице стилей и назначить их встроенному атрибуту class и индивидуальному атрибуту effect элемента. Атрибут class определяет воспроизведение элемента по умолчанию, а атрибут effect определяет воспроизведение элемента при подведении к нему указателя мыши. Раздел в конце данной главы, посвященный методам, использует динамиче- ские изменения классов для создания интерактивных и забавных Web- страпиц. Код примеров этого раздела сходен с рассмотренным примером, что дает возможность использовать данные методы на существующих Web- страницах. Таблицы глобальных стилей Предыдущие два метода предусматривают одновременное изменение стиля одного экземпляра элемента. Манипулируя таблицами глобальных стилей, сценарий может изменить одновременно стиль множества элементов. Объ- ектная модель таблиц глобальных стилей предоставляет полный доступ к таблицам глобальных стилей, определенных в документе и во внешних фай- лах. Таблицы глобальных стилей, находящиеся внутри страницы, связаны с документом посредством элемента style. Элемент Link используется для связи внешнего файла таблицы стилей со страницей. С помощью объектной модели таблиц глобальных стилей все таблицы стилей могут быть настроены индивидуально, могут быть включены и выключены. С ее же помощью можно изменить правила внутри таблицы стилей и добавить новые правила для быстрого изменения стиля всего документа. Динамическое изменение таблицы глобальных стилей является чрезвычайно мощной, но дорогостоящей операцией. При каждом добавлении пли удале- нии нового правила или изменении стиля в таблице глобальных стилей, производится перерасчет всего документа. Поэтому следует принять меры по снижению числа операций, выполняемых в таблице стилей. Если нсоб-
314 Часть III. Стиль документа и анимация ходимо произвести много изменений в документе, то эффективным методом является определение нескольких таблиц стилей с целью их активизации или отключения. Этот метод введен в разделе “Список альтернативных таб- лиц стилей" ниже в данной главе. Семейство styleSheets Документ содержит набор таблиц стилей, связанных с ним посредством се- мейства stylesheets. Семейство stylesheets содержит все таблицы глобаль- ных стилей, независимо от того, находятся ли они в документе или во внешнем файле. В семействе styleSheets, так же как и в других семействах динамического HTML, объекты перечислены в том же порядке, в котором они находятся в документе. Семейство stylesheets содержит объекты stylesheets, а не объекты элемен- тов. Имеется связь между объектами stylesheets в семействе stylesheets и объектами style и link в семействе all. Каждый объект stylesheets пред- ставляет свойство owningElement, возвращающее объект style или link, который определяет таблицу стилей. Каждый стиль и элемент Link, который связывает стиль, представляет свойство stylesheet, возвращающее объект stylesheet. Ссылка на таблицу стилей Все элементы в документе поддерживают атрибут id. Атрибут id в элементах style и Link служит двум целям: обеспечивает значение индекса для пря- мого доступа к элементу посредством семейства all и обеспечивает значе- ние индекса для прямого доступа к объекту stylesheet в семействе stylesheets. Важно понимать, что в семействе all определенный атрибут id ссылается на действительный объект style или link, тогда как в семействе stylesheets атрибут ссылается на связанный объект styleSheet. Приведен- ный ниже пример показывает установку ссылки на объект style и его свя- занный объект stylesheet с использованием id и обращение к каждому из данных объектов из другого объекта: <HTML> <HEAD> <TITLE> Объект styleSheet и элемент Style </TITLE> <STYLE ID="demo" TYPE-"text/css"> BODY {color:red) </STYLE> <SCRIPT LANGUAGE3"JavaScript"> // Возвращение объекта style. var styleElement = document.al 1["demo'*]; // Возвращение объекта styleSheet. var styleSheetObject = document.styleSheets["demo"];
Гпава 11. Динамические стили 315 // Обращение к каждому из данных объектов из другого объекта. // Оба окна сообщения отображают true. alert(styleSheetObject.owningElement ~ styleElement); alert(styleElement.styleSheet == styleSheetObject); </SCRIPT> </HEAD> <BODY> Содержание </BODY> </HTML> Список альтернативных таблиц стилей Семейство stylesheets может быть использовано для перечисления всех таблиц стилей в документе. Каждую таблицу стилей можно активизировать или отключать, включая или выключая применение таблицы стилей к доку- менту. Данный метод позволяет представить на странице множество стилей на выбор пользователю. Метод также может быть использован для обеспе- чения различных средств просмотра данных. Предоставление различных таблиц стилей имеет ряд преимуществ по срав- нению с динамическим изменением одной таблицы стилей с помощью кода. Обновление и поддержка альтернативных таблиц стилей проще, чем обнов- ление и поддержка сценариев, которые изменяют одиночную таблицу сти- лей. Кроме того, код переключения между альтернативными таблицами сти- лей более эффективен, чем код для изменения таблицы стилей, особенно если требуется изменить большое число стилей. При переключении стилей документ дважды повторно рассчитывается и снова отображается, первый раз — при отключении текущего стиля и второй раз — при активизации но- вой таблицы стилей. Напротив, при изменении одиночной таблицы стилей документ повторно рассчитывается после каждого изменения стиля. Атрибут DISABLED Элементы style и Link поддерживают атрибут disabled, который отключает таблицу стилей. Вы можете использовать этот атрибут, чтобы определить, какие таблицы стилей изначально применяются к документу. Сценарии могут позднее сбросить соответствующие значения свойства disabled эле- ментов style и Link для изменения стилей, которые применяются к доку- менту. Данный метод рассматривается в приведенных ниже примерах. Предоставление выбора средств просмотра На приведенной ниже Web-странице пользователь может переключаться между различными режимами просмотра данных. Данный метод полезен
316 Часть III. Стиль документа и анимация для обеспечения нескольких уровней детализации, на каждом из которых можно просматривать основные данные без необходимости загрузки не- скольких страниц. Данный пример требует, чтобы пользователь явно выбрал режим отображения. Ваш код может также изменить режим просмотра в ответ на различные факторы — например, размер окна браузера, как пока- зано в разделе "Адаптивные методы размещения" ниже в данной главе. <HTML> <HEAD> <TITLE> Различные режимы просмотра </TITLE> <STYLE ID="all" TYPE=”text/css”> tfheadOnly (display:none) #allText {color:red; cursor:default) </STYLE> <STYLE ID="headers" TYPE="text/css" DISABLED> #allText (display:none) tfheadOnly (color:navy; cursor:default) DIV {display:none) </STYLE> </HEAD> <BODY> <H1> Demonstration of Multiple Views</Hl> <P ID="allText” ONCLICK="document.stylesheets['headers’].disabled = false; document.stylesheets!'all'].disabled = true;"> Вы просматриваете полностью развернутую версию документа. Щелкните по данному параграфу для переключения режима просмотра. </Р> <Р ID="headOnly" ONCLICK="document.stylesheets['headers'].disabled = true; document.stylesheets[’all’].disabled = false;"> Вы просматриваете только заголовки документа. Щелкните по параграфу для переключения режима просмотра. </Р> <H2>Multiple Views</H2> <DIV> Используя объектную модель CSS, вы можете установить несколь- ко режимов просмотра данных. </DIV> <H2>Swapping Data</H2> <DIV> Вы можете также заменить режим просмотра данных. В документ можно включить стандартные данные и выборочно скрывать и просматривать их. </DIV> </BODY> </HTML> На рис. 11.1 показаны два типа отображения документа с использованием двух различных таблиц стилей. Когда пользователь щелкает по первому па-
Глава 11. Динамические стили 317 раграфу, то стиль автоматически переключается и отображается или закры- вается различная информация. С Multiple ViewilntcinotE...^fw]^ Q Multiple Views Microsoft Internet E... |Ц|й1^ M Fae Edit V'l'^.v Tiu. )!;<< Щ^Ц Demonstration of Multiple Views । . ft* s Yoi. arc viewsig an entirely <nq>anded version of the document. Click on this ft’ paragraph to switch views Multiple Views ft Using the CSS object model you can provide multiple views of the data. Swapping Data •/ You can also swap data displays You can v include predefined data m the document and selectively hide and display it. V» ______ __ .11 pp“*p““pi~ | Demonstration of Multiple Views You are viewing only the headers of the document. Click on this paragraph to switch views Multiple Views Swapping Data ”T j»| My Con Ip Iter' ЙЙ i*3 Рис. 11.1. Два типа отображения документа Выбор таблиц стилей В предыдущем примере пользователь должен был щелкнуть по параграфу, чтобы изменить режим отображения. Приведенный ниже код использует другой подход: страница содержит раскрывающийся список, в котором пользователь может выбрать режим просмотра. <HTML> <HEAD> <TITLE> Перечисление таблиц стилей </TTTLE> <STYLE ID="all" TITLE="Entire Document" TYPE=”text/css"> #headOnly (display:none) tfallText (color:red; cursor:default} </STYLE> <STYLE ID=”headers" TITLE="Headers Only" TYPE="text/css" DISABLED> SallText {display:none) #headOnly (color:navy; cursor:default} DIV (display:none) </STYLE> <SCRIPT LANGUAGE^’JavaScript">
31в Часть ///. Стиль документа и анимация function selectsheet(s) ( for (var intLoop = 0; intLoop < document.styleSheets.length; intLoop++) document.styleSheets[intLoop].disabled = (s.selectedlndex != intLoop); I </SCRIPT> </HEAD> <BODY> <Hl>Listing Alternative Style Sheets</Hl> <P>Select a View: <SELECT ONCHANGE=”selectSheet(this);"> <SCRIPT LANGUAGE="JavaScript"> // Динамическое построение списка вариантов. for (var intLoop = 0; intLoop < document.styleSheets.length; intLoop++) document.write("<OPTION>" + document.styleSheets[intLoop].title); </SCRIPT> </SELECT> <P ID=”allText"> Вы просматриваете полностью развернутую версию документа. </Р> <Р ID="headOnly"> Вы просматриваете только заголовки документа. </Р> <H2>Multiple Views</H2> <DIV> Используя объектную модель CSS, вы можете установить несколько режимов просмотра данных. </DIV> <H2>Swapping Data</H2> <DIV> Вы можете также заменить режим просмотра данных. В документ можно включить стандартные данные и выборочно скрывать и просматривать их. </BODY> </HTML>- Раскрывающийся список отображает атрибуты title таблиц стилей. Атрибу- ты title доступны для всех элементов. Они используются для назначения имен таблицам стилей. Когда пользователь выбирает элемент из списка, таблица стилей с соответствующим атрибутом title применяется ко всему документу. На рис. 11.2 показаны два доступных режима првсмотра данного документа. Дополнительные режимы просмотра добавляются просто путем определения дополнительных таблиц стилей.
Гпава i 1, Динамические стили 319 Q I isting Style Sheets • Microsoll Intel FIPIE5 Q Listing Style Sheets • Microsoft Inter ИГ»! 13! j fie So Fjvorfw .............................-3 Listing Alternative Style Sheets J Select a view: You are viewi _ version of the document %*f M Multiple Views >5 <> Using the CSS object model you can provide multiple views of the data ?f $ Swapping Data You can also swap data displays. You can £* include predefined data in the document and selectively hide and display it [ ;• i ’> f iJSj My COnpUt* Listing Alternative Style Sheets :$ Select a view | Handers Only Д| | Entire Document u You are viewii document Multiple Views Swapping Data My Computer Meodei; UH/ Рис. 11.2. Сравнение двух различных средств просмотра Случайные таблицы стилей Предыдущий пример демонстрирует метод, который позволяет пользовате- лю вручную выбрать таблицы стилей, но не обязательно, чтобы пользова- тель осуществлял данный выбор вручную. Вы можете написать код, который автоматически применяет случайную таблицу стилей, так что при каждом посещении данной страницы содержание отображается разными способами. Этот простой метод делает Web-узлы более интересными и динамическими. В разделе "Адаптивные методы размещения" ниже в данной главе продемонстрирован метод изменения внешнего вида страницы на основе среды пользователя. В общем, лю- бое событие может быть использовано для изменения внешнего вида документа, неза- висимо от источника изменения: пользователь, результат выполнения действия ш.л таймер. Таблицы стилей, зависящие от среды HTML 4.0 определяет механизм связи различных таблиц стилей с различ- ными типами средств передачи информации. Браузер Internet Explorer 4.0 поддерживает два типа средств передачи информации: screen (экран) и print (печать). Вы можете определить различные таблицы стилей, которые применяются к документу при отображении на экране или выводе на пе-
320 Часть III. Стиль документа и анимация чать. Приведенный ниже код демонстрирует определение трех таблиц сти- лей, из которых первая служит для печати, вторая — для просмотра на эк- ране и третья — для всех режимов просмотра документа: <STYLE TYPE="text/css" MEDIA-"screen"> /‘ Применяется, если документ просматривается на экране */ Hl {colorznavy; text-align:center} Р (margin-left:10pt} </STYLE> <STYLE TYPE="text/css" MEDIA-"print"> /* Применяется при печати документа. */ Hl (co.lor:black} Г (margin-left:5pt) </STYLE> <STYLE TYPE“"text/css" MEDIA="scroen, print"> /* Применяется при печати или отображении документа */ Н2 (font-size:12pt} </STYLE> Если атрибут media опущен, то таблица стилей применяется ко всем типам отображения документа. Атрибут media является свойством объекта stylesheet и элементов style и Link. Вы можете динамически изменить данное свойство для переключения средства воспроизведения, к которому применяется таблица стилей. В следующем разделе содержится пример ко- да, определяющий таблицы стилей, применяемые на данный момент к ото- бражению документа на экране. Свойство cssText объекта styleSheet В разделе “Свойство cssTexC выше в данной главе было введено свойство cssText, как свойство стиля для всех элементов. Кроме того, каждый объект stylesheets представляет свойство cssText, доступное только для чтения. Данное свойство представляет таблицу глобальных стилей, отформатиро- ванную как текст. Это свойство очень полезно для быстрого просмотра таб- лицы стилей, связанной с данной страницей. Приведенный ниже код, по- мещенный в конце документа, выводит все таблицы стилей, которые при- менены па данный момент к документу: <SCRIPT LANGUAGE-"JavaScript"> var ss - document.styleSheets; document.write("<PRE>"); for (var intLoop - 0; intLoop < ss.length; intLoop++} // Таблица стилей применена к экрану и н^ отключена, if ((("" == ss(intLoop).media} H (-1 != ss[intLoop].media.indexOf("screen"))) &&
Гпава 11. Динамические стили 321 (!ss[intLoop].disabled)) document.write(ss[intLoop].cssText); document.write("</PRE>"); </SCRIPT> Семейство rules Каждая таблица стилей содержит собственное семейство правил. Правило представляет собой комбинацию описания стиля (например, color:red) и его селектора (например, hi). Используя данное семейство, вы можете ди- намически изменить описание. Селектор предназначен только для чтения. Если необходим новый селектор, то следует удалить данное правило и доба- вить новое в таблицу стилей. Правила добавляются и удаляются с помощью методов addRule И removeRule объекта stylesheet. Каждое правило в семействе rules представляет собой одиночный селектор и описание, независимо от того, как оно было определено в таблице стилей. Приведенный ниже пример демонстрирует таблицу стилей, которая содержит сгруппированные селекторы и определена с помощью семейства rules: <STYLE TYPE="text/css"> Hl, H2, P EM (color:green) </STYLE> <SCRIPT LANGUAGE="JavaScript"> var rules = document.styleSheets[0].rules; for (var intLoop = 0; intLoop < rules.length; intLoop++) document.write("Rule: " + rules[intLoop].selectorText + ”, Style: " + rules[intLoop].style.cssText + "<BR>”); </SCRIPT> Приведенный выше код выводит три отдельных правила, поскольку группи- рование производится отдельно в объектной модели, так что доступ и изме- нение индивидуальных стилей выполняется проще. Данный код также де- монстрирует два из трех свойств, доступных для каждого правила. Свойство selectorText доступно только для чтения и представляет часть селектора в правиле. Свойство style работает так же, как и свойство style индивиду- альных элементов. Оно позволяет изменять стиль селектора. Добавление и удаление правил Метод addRule позволяет добавить новое правило в таблицу стилей. Метод removeRule удаляет существующее правило из таблицы стилей. По умолча- нию новые правила добавляются в конец таблицы стилей и имеют приори- тет над остальными правилами, которые были определены ранее. Поскольку
322 Часть Ш. Стиль документа и анимация каждая таблица стилей объединяется независимо, то новое правило, добав- ляемое в первую таблицу стилей, имеет более высокий приоритет, чем ос- тальные правила в данной таблице. Но такое правило имеет более низкий приоритет, чем правила в таблицах стилей, которые находятся ниже данной таблицы. Поэтому, чтобы гарантировать новому правилу приоритет над су- ществующими, следует добавить его в последнюю таблицу стилей, которая была определена в документе: var intSS = document.stylesheets.length; if (0 < intSS) // Убедитесь в наличии таблицы стилей, в которую будет // добавлено правило. document.stylesheets[intSS — 1].addRule("Hl", "color:red; font-size:18pt"); Если вам требуются расширенные возможности управления положением правила в таблице стилей, то вы можете добавить правило в семейство rules в указанное положение, определив индекс в качестве последнего параметра для метода. Данный код добавляет правило в начало таблицы стилей: var intSS = document.styleSheets.length; if (0 < intSS) // Убедитесь в наличии таблицы стилей, в которую будет // добавлено правило. document.styleSheets[intSS — 1].addRule("Hl", "color:red; font-size:18pt", 0); // Добавляет правило в первую позицию Во всех случаях метод addRule возвращает индекс, определяющий место до- бавления правила в семейство rules. В данном примере индекс определен явно, и метод addRule возвращает 0. Метод removeRuie выполняет обратную операцию и возвращает индекс уда- ляемого правила. Приведенный ниже код демонстрирует удаление первого правила из последней таблицы стилей: var intSS = document.styleSheets.length; if (0 < intSS) // Убедитесь в наличии таблицы стилей, из которой будет // удалено правило. document.styleSheets[intSS — 1j.removeRuie(0); Таблицы связанных стилей и правила Все таблицы стилей содержат свойство readonly, определяющее возмож- ность изменения таблицы стилей. Для таблиц связанных стилей это свойст- во возвращает true. Однако таблицы связанных стилей позволяют добавлять и удалять правила. Изменение таблицы связанных стилей влияет только на текущий отображаемый экземпляр документа. Добавление правила в табли-
Глава 11. Динамические стили 323 цу связанных стилей не приводит к обновлению других документов, кото- рые совместно используют данную таблицу стилей. На данный момент от- сутствует способ динамического изменения таблицы стилей несколькими документами (невозможно добавить правило в каждый документ). Импортированные таблицы стилей Вы можете использовать оператор ©import в таблице стилей для импорта другой таблицы стилей. С помощью объектной модели можно динамически получить доступ к импортированным таблицам стилей, добавлять и удалять их. Импортированные элементы таблицы стилей представлены семейством imports, каждый элемент которого является объектом stylesheet. Импорти- рованная таблица стилей может импортировать другую таблицу стилей. По- этому для определения таблицы стилей, в которой находится импортиро- ванная таблица, объект.styleSheet представляет свойство parentstylesheet, которое возвращает объект stylesheet, определяющий импорт. Для таблиц стилей высшего уровня данное свойство возвращает null. Метод addimport объекта stylesheet использует в качестве аргумента стро- ку адреса URL. В соответствии со спецификацией CSS импортированные правила стилей всегда находятся в начёте таблицы стилей и, следовательно, в начёте последовательности каскадирования. Таким образом, все правила в импортированных таблицах стиле!! имеют более низкий приоритет по срав- нению с правилами, которые уже находятся в таблице стилей. Приведенный ниже код импортирует таблицу стилей cool.css в первую таблицу стилей в семействе styleSheets: document.styleSheets[0].addimport("URL('cool.css Для удаления импортированного элемента из семейства imports использует- ся метод removeimport. Приведенный ниже фрагмент кода удаляет первый импортированный элемент из таблицы стилей: document.styleSheets(0).removeimport(0); Добавление новых таблиц стилей Таблицы стилей можно добавить в документ, используя метод creatcStyleSheet. По умолчанию метод createStyleSheet добавляет новую таблицу стилей последней в семейство styleSheets. Для добавления новой таблицы связанных стилей укажите адрес URL в качестве первого аргумен- та. В качестве второго аргумента задайте индекс для определения места вставки таблицы стилей. Если требуется создать таблицу несвязанных сти- лей, вставьте ее в определенную позицию в семействе stylesheets, и укажи- те null в качестве первого аргумента. . . ..
324 Часть III. Стиль документа и анимация Создатель таблиц стилей Приведенный ниже пример демонстрирует динамическое изменение табли- цы глобальных стилей документа для быстрого изменения внешнего вида всех элементов одного типа. При этом используется набор фреймов, в кото- ром левый фрейм содержит набор стилей, а в правом фрейме находится со- держание, к которому должны быть применены стили. Пользователь выби- рает стиль из левого фрейма, а затем щелкает по элементу в правом фрейме. Все элементы данного типа будут немедленно обновлены. Имя тега элемен- та, к которому будет применен стиль, отображается в строке состояния. Данный пример использует три файла. Файл stylizer.htm содержит набор фреймов и большую часть основного кода для передачи стиля из фрейма стилей во фрейм содержания. Файл styles.htm содержит таблицу предлагае- мых стилей. В файле contents.htm находится содержание, к которому долж- ны быть применены стили. В данном примере соблюдаются следующие правила: □ Обработчики событий для документов стиля и содержания записаны в наборе фреймов. □ Стиль ячейки в таблице документа стилей изменяется путем изменения его имени класса. Выбранная таблица внутренних стилей ячейки опреде- ляет цвет и размер шрифта, которые должны быть использованы в эле- ментах, выбранных пользователем в документе. Поэтому граница ячейки, которая указывает, что данный элемент выделен, не может быть частью своего внутреннего стиля. Граница определяется в таблице глобальных стилей. □ Метод addRule используется для добавления новых правил в документ содержания. □ Строка состояния обновляется на основе положения указателя мыши. На рис. 11.3 показано окно приложения создателя стилей. О lhe Styluer • Miciosutt Internet Explorer Select a style and click on the document to apply it. Small White and Black Big Red and Wliite Medium K:ivy anti Yellow Demo Contents Here are some demo contents to test the stylizer on. Select a style from the left pane, and click on in this pane. The element you click and aU elements of the same type wiQ SOEHEEt0 match that style This technique adds new rules to the style sheet ^or this document. Рис. 11.3. Окно приложения создателя стилей
Глава 11. Динамические стили 325 Файл stylizer.htm. Приведенный ниже документ с набором фреймов разде- ляет экран на два фрейма: левая половина отображает список параметров стиля, а правая — отображает документ, к которому должны быть примене- ны стили. Код, обрабатывающий связи между двумя другими документами, находится внутри данного документа. <нтмь> <HEAD> <TITLE> Stylizer </TITLE> <SCRIPT LANGUAGE="JavaScript"> window.curStyle = null; function selectstyle() { // Выделение выбранной ячейки стиля, var el = this.parentwindow.event.srcEiement; if ("TD" == el.tagName) { if (null != curStyle) curStyle.className = curStyle = el; curStyle.className = "selected"; } } function addStyle() ( // Добавление в документ нового правила для выбранного стиля, if (null != curStyle) ( var srcWin = this.parentwindow; var tag = srcWin.event.srcEiement.tagName; srcWin.document.styleSheets[0].addRule(tag, curStyle.style.cssText); ) } function hookupEvents() ( < • ' /* Связывает все события нажатия фрейма с соответствующей функцией в данном документе. */ window.styles.document.onclick = selectstyle; window.content.document.onclick = addStyle; ) </SCRIPT> </HEAD> <FRAMESET ONLOAD="hookupEvents();" COLS="170, *"> <FRAME SRC="styles.htm" NAME="styles"> <FRAME SRC="content.htm" NAME="content"> </FRAMESET> </HTML>
326 Часть III. Стиль документа и анимация Файл styles.htm. Приведенный ниже документ содержит таблицу стилей, из которой пользователь может выбрать стиль для использования в документе. Добавление большего количества ячеек в таблицу может расширить список стилей. <HTML> <HEAD> <TITLE>Style List</TITLE> <STYLE TYPE="text/css"> /* Данный стиль используется для выделения выбора пользователя. */ .selected (border:2рх black solid} </STYLE> </HEAD> <BODY> <P>Select a style and click on the document to apply it.</P> <!— Внутренний стиль ячейки определяет стиль, который может быть применен к документу при выборе ячейки. Данный стиль просто копируется вместо старого стиля. —> <TABLE> <TR> <TD STYLE="background:white; color:black; font-size:12pt"> Small White and Black </TD> </TRxTR> <TD STYLE=”background:red; color:white; font-size:18pt"> Big Red and White </TD> </TRxTR> <TD STYLE="background:navy; color:yellow; font-size:14pt"> Medium Navy and Yellow </TD> </TR> </TABLE> </BODY> </HTML> Файл contenthtm. К содержанию приведенного ниже документа применены выбранные стили. Небольшой сценарий в данном документе используется для отображения имени тега элемента, к которому должен быть применен стиль в строке состояния. <нтмь> <HEAD> <TITLE> Демонстрационное содержание </TITLE> <SCRIPT LANGUAGE^”JavaScript"> function updateStatus() (
Глава 11. Динамические стили 327 /* Отображает имя элемента, над которым находится указатель мыши.К данному типу элемента будет применен новый стиль. */ window.defaultStatus = event.srcElement.tagName; </SCRIPT> <STYLE TYPE="text/css”> /* Блок стиля, в который будет добавлено новое правило. */ </STYLE> </HEAD> <BODY ONMOUSEOVER="updateStatus();”> <Hl>Demo Contents</Hl> <P>Here are some demo <EM>contents</EM> to test the <EM>stylizer</EM> on.</P> <P>Select a style from the left pane, and click on <STRONG>text</STRONG> in this pane. The element you click and all elements of the same type will <STRONG>change</STRONG> to match that style. <P>This technique adds new rules to the style sheet for this document. </BODY> </HTML> События таблицы стилей Объект stylesheet нс создается и не добавляется в семейство stylesheet, пока не будет загружена вся таблица стилей, включая полную загрузку всех таблиц связанных или импортированных стилей. Для отслеживания состояния таблицы стилей элементы style и Link представляют события onreadystatechange И onload. Свойство readyState возвращает строку, кото- рая представляет текущее состояние элемента. Данные события и свойство readyState аналогичны членам с такими же именами документа и окна. Во время анализа таблицы стилей значение readyState равно loading. После загрузки всей таблицы стилей значение readystate изменяется на complete. Непосредственно перед переходом в состояние complete создается объект stylesheet, который добавляется в семейство stylesheet. События onreadystatechange или onload могут быть использованы для отслеживания момента, когда таблица стилей становится доступной. Событие onload все- гда возникает сразу же после события onreadystatechange в момент, когда таблица стилей переходит в состояние complete. Приведенный ниже доку- мент демонстрирует последовательность событий. HTML> <HEAD> <TITLE> События таблицы стилей </TITLE> <STYLE TYPE="text/css"
328 Часть III. Стиль документа и анимация ONREADYSTATECHANGE» ’’alert (’ readyState: ' + this. readyState); ’’ ' . ONLOAD="alert(1 load event');"> Hl (color:red) c/STYLE> c/HEAD> cBODY> cHl>HeadingC/Hl> c/BODY> c/HTML> Все окна отображают приведенные ниже сообщения в указанном порядке: 1. readyState: loading 2. readyState: complete 3. load event Таблица стилей загружается в документ синхронно. Пока загружается таб- лица стилей, остальная часть документа не анализируется и не воспроизво- дится. События onreadystatechange И onload используются также для вывода сообщений о состоянии документа в строке состояния, как показано ниже: <HTML> CHEAD> CTITLE> Состояние readyState документа c/TITLE> CSCRIPT LANGUAGE»”JavaScript’’> function updateStatus(msg) { window.defaultstatus = msg; ) C/SCRIPT> c!— Обеспечивает обновление загружаемой таблицы стилей. —> CLINK REL="styleSheet” TYPE="text/css” HREF="dhtml.css" TITLE»"Default Sheet" ONREADYSTATECHANGE="updateStatus('StyleSheet[' + . this.title + ']: ' + this. readyState) ;’’> CSCRIPT LANGUAGE»’’JavaScript’’> // Позволяет пользователю узнать, что документ еще находится // в состоянии анализа. , j, updateStatus ("Parsing: ’’ + document. title) ; C/SCRIPT> C/HEAD> CBODY ONLOAD="updateStatus(");"> cHl>Status Trackingc/Hl> C/BODY> C/HTML>
Гпава 11. Динамические стили 329 Если таблица стилей не может загрузиться, поскольку превышена длитель- ность паузы соединения с сервером или данный файл отсутствует, то собы- тия onload и onreadystatechange, которые указывают на завершение загруз- ки, не возникают. На данный момент в случае невозможности загрузки таб- лицы связанных стилей ошибка не генерируется и отсутствует явное событие ошибки для отслеживания данной ситуации. Одним из методов решения проблемы является установка флага в обработчике событий onload. Если данный флаг не установлен, то ошибка должна возникнуть в ходе за- грузки таблицы стилей: <HTML> <HEAD> <TITLE> Отслеживание ошибки загрузки </TITLE> <LINK REL="styleSheet" TYPE="text/css" HREF="dhtml.css" TITLE-"Default Styles" ID="ssl" ONLOAD="this.downloaded = true; // Success!"> <SCRIPT LANGUAGE^'JavaScript"> /* Если данное свойство не существует, то возникает ошибка. Свойство будет добавлено в элемент, а не в объект styleSheet. */ if (null — document.all.ssl.downloaded) alert("Error downloading style sheet."); </SCRIPT> </HEAD> <BODY> <Hl>Error Tracking</Hl> </BODY> </HTML> Адаптивные методы размещения Объектная модель CSS позволяет документам адаптироваться к пользова- тельской среде. Большая часть примеров в данной главе использует динами- ческие стили для добавления эффектов или для предоставления пользовате- лю возможности выбора вручную альтернативных таблиц стилей. Схема размещения документа может быть также изменена на основе разрешения экрана, размера окна или других значений клиентской системы. Ниже пере- числены несколько эффективных приемов, которые вы можете использовать для создания страниц, адаптирующихся к пользовательской системе: □ Опишите исходный статический стиль, используя таблицу стилей. При необходимости используйте установки системы для значений цвета и ти- па шрифта. □ Опишите альтернативные таблицы стилейГдля различных окружений. До- бавьте сценарий, который устанавливает исходный стиль на основе ок- ружения.
330 Часть III. Стиль документа и анимация □ Используйте событие resize элемента Body или других элементов для ди- намического изменения активизированных таблиц стилей на основе раз- мера окна. □ Для более сложных систем создайте правила динамически, свяжите их с документом и измените стили. Первые три метода легко добавить в документ. Все стили описываются с помощью CSS и программирование используется только для активизации и отключения соответствующей таблицы стилей. Используя последний метод, вы можете, используя описанные выше методы, создать страницы, изме- няющиеся за счет прямого манипулирования существующими правилами и добавления новых правил. Приведенный ниже пример использует первые три метода адаптивного из- менения размещения. Изменение схемы размещения содержания в доку- менте осуществляется в соответствии с тремя главными таблицами стилей в зависимости от размера окна. Данные три схемы размещения объединены с одной из двух цветовых гамм на основе числа доступных цветов. Кроме то- го, панель перехода в верхней части окна использует цветовую гамму на ос- нове системных меню. Все таблицы стилей включены в документ. В про- тивном случае они могут быть определены как таблица связанных стилей и совместно использованы на всем Web-узле. На рис. 11.4 показаны две альтернативные схемы размещения содержания документа. Adaptive Layout Example ... ЁЗ1 12 Edit yew Qo Fj.o ‘ Adaptive Layout Example - Microsoft Ini... HlslEJ iResise !fl', window .tor an exAW'lr;. | Floating Elcineнts Floating Elements The figure abwe that elements can move into and out of the flow based on the window sire. MLComputet i in-.: ;Dynarnj>: HTML1 the. window for ar vr.!- Tv. 1 '-hat t-lcmtnt? can move ink said ЧЦ , f ihc fl*-w VLtJ-rd г*.; the j £ie fiu tazo’Sei Цйр «№$ of c sibii. , suppoited The tt-nt and the Lnotins; tuinoni trnniJttionrd tA oobnwr* anvatnt aj j^MyCwpotef Рис. 11-4. Схемы размещения адаптивного документа в окнах с различной шириной Наиболее очевидным отличием между окнами является размер полей. В уз- ком окне справа от текста появляется поле, которое в широком окне запол- няется текстом.
Гпава 11. Динамические стили 331 Ниже приведен полный листинг данного примера: <HTML> <HEAD> <TITLE> Пример адаптивной схемы размещения </TITLE> <STYLE TYPE="text/css" ID="default"> /* Таблица стилей по умолчанию всегда применяется к документу. */ /* Определение строки меню для соответствия встроенным меню пользовательской системы. */ .menu A.highlight (background:highlight; color:highlighttext) .menu {background:menu} .menu P (margin-left:5pt; margin-right:5pt) .menu A (color:menutext; text-decoration:none; font:menu) /* Определение полей по умолчанию. */ body (margin-top:Opt; margin-left:Opt) .centerindent (margin-left:5pt; margin-right:5pt) .leftindent (margin-left:5pt; margin-right:5pt} .rightindent (margin-left:5pt; margin-right:5pt} Hl (text-align:center} .outline (border:lpt solid gray; margin:2pt 2pt 2pt 2pt) </STYLE> <STYLE TYPE="text/css" ID="narrowScreen"> /* Дополнительные правила стилей для узкого экрана; все содержание для широких экранов скрыто. */ .wide (display:попе} </STYLE> <STYLE TYPE="text/css" ID="midScreen"> /* Правила для экранов среднего размера. Содержание для узкого экрана скрывается. */ .narrow (display:попе} .floatLeft (margin-left:0; width:150; float:left) </STYLE> <STYLE TYPE="text/css" ID="wideScreen"> /* Наилучшая схема размещения на самом широком экране. */ .centerindent (margin-left:15%; margin-right:15%) .leftindent (margin-left:35%; margin-right:5%} .rightindent (margin-left:5%; margin-right:35%} .floatLeft (margin-left:-154; width:150; float:left) .narrow (display:none} </STYLE> <STYLE TYPE="text/css" ID="4bit”> /* Число цветов равно 4 или меньше»*/ BODY (color:red; background:white) </STYLE>
332 Часть Ш. Стиль документа и анимация <STYLE TYPE="text/css" ID="8bit"> /* Таблицы стилей для 8 или большего числа битов */ BODY (background:URL(fancy.gif)) Hl (color:purple} H2 {color:navy) </STYLE> <SCRIPT LANGUAGE="JavaScript"> // Выберите таблицу стилей для доступного количества цветов, var ss = document.styleSheets; ss ("4bit"].disabled = (screen.colorDepth >= 8); ss{''8bit"J .disabled = ! (ss("4bit"] .disabled); function updateLayout() { // Изменение таблицы стилей на основе доступной ширины экрана, var ss = document.styleSheets; ss("wideScreen").disabled = (450 > document.body.offsetWidth); ss["midScreen").disabled = (!ss("wideScreen"].disabled || 300 > document.body.offsetWidth); ss["narrowScreen"].disabled = !(ss("wideScreen").disabled && ss["midScreen"].disabled); ) function highlight() ( // Выделение элемента Anchor в меню. if ("A" == event.toElement.tagName) event.toElement.className = "highlight"; ) function cleanup() ( // Очистить класс. if ("A" == event.fromElement.tagName) ( event.fromElement.className = ) </SCRIPT> , </HEAD> <BODY ONRESIZE="updateLayoUt();"> <SCRIPT LANGUAGE="JavaScript"> /* Данный вызов находится в теле, поскольку метод updateLayout основан на доступном элементе Body. */ updateLayout О ; </SCRIPT> <!— Вывод строки меню с использованием пользовательских установок для меню. —> <DIV CLASS="menu" ONMOUSEOVER="highlight()” ONMOUSEOUT="cleanup()”>
Глава 11. Динамические стили 333 <Р><А HREF="home.htm">Home</A>4nbsp;Snbsp;&nbsp; <А HREF="search.htm">Search</A>&nbsp;Snbsp;Snbsp; <A HREF="about. htm">About</AX/P> </DIV> <Hl>Adaptive Layout</Hl> <DIV CLASS=,'centerInclent,’> Данный пример демонстрирует использование динамических стилей для создания страницы, которая адаптируется к окружающей среде. Строка меню использует системные установки для количества цветов. Для систем с ограниченной цветовой поддержкой в документе используется только черный и белый цвета. Схема размещения будет изменяться в зависимости от размера окна. Содержание также модифицируется при изменении окружения. </DIV> <DIV CLASS=”leftIndent"> <H2>Floating Elements</H2> <TABLE ID="tleft" CLASS="floatLeft"> <TR> <TD CLASS=”outline" VALIGN=”Top”> Adaptive Layout and <BR> Dynamic HTML! ' <P>Resize the window<BR> for an example. </TD> </TR> </TABLE> <!— Обращение к плавающему элементу изменяется в зависимости от размера экрана. —> <P>The figure <SPAN CLASS="wide">to the left</SPAN> <SPAN CLASS="narrow">above</SPAN> demonstrates -that elements can move into and out of the flow based on the window size. </P> <P>The rendering of the page changes based on the window size and the number of colors supported. The text and the floating element are repositioned to optimize the amount of real estate available on the screen. </P> </DIV> <DIV CLASS="rightIndent"> <H2>Conditional Data</H2> <P> В зависимости от окружения будут отображаться различные данные. </Р> <Р CLASS=”wide" STYLE="color:red”> Вы просматриваете версию документа для широкого экрана. </Р>
334 Часть III. Стиль документа и анимация <Р CLASS="narrow" STYLE="color:red"> Документ имеет отличный стиль, поскольку ширина окна просмотра мала. </Р> </DIV> <DIV STYLE="display:none"> <!— Данное сообщение отображается, только если не поддерживается таблица стилей. —> Данную страницу лучше всего просматривать в браузере, который поддерживает CSS и динамический HTML. </DIV> </BODY> </HTML> Данный документ независимо адаптируется к пользовательской среде. В до- кументе могут быть также учтены пользовательские действия, которые из- меняют режим отображения. При реагировании документа с адаптивным размещением на инициируемые пользователем действия, стили пользовате- ля должны иметь приоритет над автоматически применяемыми стилями. Например, если пользователь явно скрывает или показывает данные, то из- менения схемы размещения должны отражать выбор пользователя. Про- стейшим способом установки приоритета для стилей пользователя является помещение их в таблицы внутренних или глобальных стилей в ходе исполь- зования таблиц глобальных стилей для адаптивных стилей размещения. Методы отображения данных Метод адаптивного размещения, автоматически изменяющий документ, ос- нован на пользовательской среде. Методы отображения данных фокусиру- ются на взаимодействии пользователя с документом для отображения дан- ных. Например, вместо представления пользователю большого документа вы можете в исходном состоянии отображать только заголовки и другую свя- занную с ними информацию. Пользователь затем может щелкнуть по заго- ловку или другому текстовому элементу для отображения или скрытия свя- занной информации, что делает документ более интерактивным. Данные методы также хорошо адаптируются на браузерах низкого уровня, и которых документ отображается целиком без дополнительных элементов интерак- тивного взаимодействия. Использование указателей мыши для выделения содержания При создании динамического документа вы мЛжете преобразовывать раз- личные элементы в области нажатия или устанавливать для них специаль- ные модели поведения. Чтобы использовать данные элементы, пользователь
Глава 11. Динамические стили 335 должен знать, что представляют собой данные элементы. Пользователю лег- че определить назначение элемента, если изображение указателя мыши ме- няет вид над различными элементами. По умолчанию указатель мыши над информационным элементом принима- ет I-образную форму, что указывает на возможность выделения текста. Над элементами поведения, например, ссылками в документе, указатель мыши превращается в изображение руки, что указывает на возможность нажатия элемента. Браузер Internet Explorer 4.0 предоставляет Web-разработчику возможность управления видом указателя мыши с помощью свойства CSS cursor, позво- ляющему определять вид указателя мыши при подведении его к элементу'. Например, при создании области нажатия лучше использовать указатель мыши в виде руки или другого типа указателя, чем I-образная форма. В гла- ве 1 приведена таблица, содержащая список всех типов указателей мыши, которые можно установить посредством свойства cursor. Приведенный ниже код отображает указатель в виде руки, когда он нахо- дится над элементом Н1: <Н1 STYLE="cursor:hand" ONCLICK=”alert('clicked1);" ONSELECTSTART="event.returnValue = false;"> Указатель мыши превращается в руку при подведении его к данному заголовку. </Н1> Событие onseiectstart обрабатывается для отключения возможности выде- ления текста внутри заголовка. Отмена данного события путем возвращения значения false запрещает пользователю выделять текст внутри заголовка. Это не запрещает пользователю выделять текст. Выделение текста может быть начато за пределами заголовка и будет расширено с включением со- держания заголовка. Данная модель поведения установлена по умолчанию для ссылок. Скрытие и отображение данных Приведенный ниже пример содержит общий код, который динамически отображает и скрывает имеющиеся данные. <HTML> <HEAD> . <TITLE> Отображение и скрытие данных </TITLE> <STYLE TYPE="text/css"> body (background:white) •expandable (color:blue; cursor:hand) .expanded (color:black; font-size:”12pt")
336 Часть III. Стиль документа и анимация .collapsed (display:none) </STYLE> <SCRIPT LANGUAGE="JavaScript"> // Общий код отображения function outlinert) ( // Получение дочернего элемента, var child = document.all(event.srcElement.getAttribute("child", false)]; // Если дочерний элемент существует, то он будет развернут или // свернут. if (null != child) child.className = child.className == "collapsed" ? "expanded": "collapsed"; ) </SCRIPT> </HEAD> <BODY ONCLICK-"outliner();"> <H1 CLASS="expandable" child="info"> Click here for more information. </Hl> <DIV ID="info" CLASS="collapsed"> Данное содержание не отображается в исходном состоянии. Для отображения содержания щелкните по заголовку выше данного текста. </DIV> </BODY> </HTML> В этом примере любой элемент ведет себя как источник нажатия (click source), управляющий отображением или скрытием определенной информа- ции. Чтобы установить подобное поведение элемента, назначьте ему имя класса expandable и укажите для него индивидуальный атрибут child. Класс expandable определяет отображения указателя мыши в виде руки при нахождении над элементом данного класса. Класс expandable только стан- дартизирует внешний вид источников нажатия, поэтому он необязателен. Вы можете изменить класс для дальнейшей стандартизации внешнего вида разворачиваемых элементов. Индивидуальный атрибут child должен содержать идентификатор (id) дан- ных, которые должны быть отображены или спрятаны. Щелчок мышью по разворачиваемому элементу приводит к изменению имени класса данных с collapsed на expandable или наоборот, в зависимости от того, отображается элемент или скрыт. Вам следует установить для класса данных имя collapsed или expanded для определения его исходного внешнего вида.
Гпава 11. Динамические стили 337 Развертывание и свертывание списков В предыдущем примере было показано, как в общем случае отображать или сворачивать содержание. Этот пример может быть расширен для создания разворачиваемого и сворачиваемого списка элементов. В приведенной ниже схеме продемонстрировано выделение подкласса элементов контейнера спи- ска (иь или ol) для поддержки отображения списка. При помещении дан- ного кода на страницу, списки на странице будут поддерживать разворачи- вание и сворачивание. <HTML> <HEAD> <TITLE> Разворачивание и сворачивание списков </TITLE> <STYLE TYPE="text/css"> /* Определение таблицы стилей */ UL (cursor:hand; color:navy) UL UL {display:none; margin-left:5pt) .leaf {cursor:text; color:black) </STYLE> <SCRIPT LANGUAGE»"JavaScript"> function checkParent(src, dest) ( // Поиск определенного предка текущего элемента. while (src != null) { if (src.tagName == dest) return src; src = src.parentElement; } return null; ) function outlined ( // Разворачивание или сворачивание при нажатии элемента списка. var open = event.srcEiement; // Проверка того, что щелчок был произведен внутри элемента // LI. Данная проверка позволяет использовать форматирование // HTML внутри списков. var el = checkParent(open, "LI"); if (null != el) ( var pos = 0; // Search for a nested list. for (pos = 0; pos < el.children.length; pos++) if ("UL" == el.children(pos].tagName) break; if (pos == el.children.length) return; }
338 Часть III. Стиль документа и анимация else return; el = el.children(pos]; if ("UL" == el.tagName) { // Разворачивание или сворачивание вложенных списков. if ("" = el.style.display) el.style.display = "block"; else el.style.display = ""; ) event.cancelBubble = true; document.onclick = outline; </SCRIPT> </HEAD> <BODY> <UL> <LI>Item 1 <UL> <LI CLASS="leaf">Subitem 1 <LI>Subitem 2 <UL> <LI CLASS="leaf">Subsubitem 1 </UL> </UL> </LI> <LI CLASS="leaf">Item 2 </UL> </BODY> </HTML> Создание разворачиваемой таблицы содержания Комбинируя разворачиваемый и сворачиваемый списки содержания с эф- фектами мыши, которые были рассмотрены ранее в данной главе, можно создать интерактивное меню. Код HTML, используемый для создания дан- ного документа, является стандартным кодом HTML для создания вложен- ных списков. Совместное использование таблиц стилей и стандартного кода HTML позволяет создать интерактивные элементы. Поскольку используется стандартный список, то данная страница плавно деградирует на браузерах низкого уровня, которые не поддерживают динамический HTML. Напри- мер, браузер Internet Explorer 3.0 отображает документ как стандартный маркированный список.
Глава 11. Динамические стили 339 Код данного примера находится на прилагаемом компакт-диске. Для созда- ния разворачиваемых меню необходимо выполнить следующие действия: 1. Создайте маркированный список для представления разворачиваемых элементов, но сделайте список более дружественным для пользователя и замените стандартные маркеры на изображения. С помощью динамиче- ского HTML данные изображения изменяются для представления раз- вернутого и свернутого состояния каждого элемента. Эти два состояния определены при помощи таблиц стилей, как показано в приведенном ниже фрагменте кода. Определен специальный класс open для представ- ления развернутого состояния. Поскольку добавление класса open уста- навливает более высокий приоритет правила стиля CSS, чем в случае по умолчанию, то отображается файл open.gif. /* Для указания открытой и закрытой папки используются файлы GIF вместо стандартных маркеров. */ UL.toc LI {list-style-image:url(close.gif)) UL.toc LI.open (list-style-image:url(open.gif)) /* Цвета для выделенных команд меню и для выделенных ссылок. */ UL.toc A:active, UL.toc A.select {color:white; background:blue) UL.toc .over {color:red) /* Цвет выделенного фрагмента *7 2. Поместите дочерние элементы всех элементов внутрь вложенного списка. Код в данном примере требует, чтобы вложенный тег UL следовал сразу за элементом Anchor, представляя тему заголовка, как показано в приве- денном ниже фрагменте кода. Поэтому расширенный HTML не может быть использован внутри ссылки высшего уровня. Если требуется ис- пользование расширенного HTML, то содержащийся сценарий можно расширить для пропуска дополнительных элементов. <ы> <А HREF="chl/overview.htm">Overview of HTML and CSS</A> <UL> <LIXA HREF="chl/html40.htm" TITLE="HTML 4.0”> HTML "4.0"</Ax/LI> • ' ’ <LIXA HREF="chl/css.htm" TITLE=”CSS Features'^ CSS Features</AX/LI> <LlxA HREF="chl/cssp.htm" TITLE=”CSS Positioning"> CSS Positioning</AX/LI> <LIXA HREF=”chl/settings.htm" TITLE="Systern"> System Settings</Ax/LI> </UL> </LI> 3. Объедините данную схему размещения с соответствующим сценарием для создания полностью разворачиваемого списка.
340 Часть III. Стиль документа и анимация Полный текст документа и сценария, который необходим для создания раз- ворачиваемого списка, приведены в следующем коде. Данный пример может быть расширен дочерними элементами просто путем добавления дополни- тельного HTML. <HTML> <HEAD> <TITLE> Содержание </TITLE> <STYLE TYPE="text/css"> BODY (background:navy; color:white) UL.toc (cursor:hand) /* Установка изображения для маркированного списка. */ UL.toc LI (list-style-image:url(close.gif)} UL.toc LI.open (list-style-image:url(open.git)} UL.toc UL (list-style:none) /* Скрытие дочерних элементов по умолчанию. */ UL.toc UL (display:none) /* Отображение дочерних элементов. */ UL.toc UL.expanded (display.-block) UL.toc LI A (text-decoration:none; color:yellow; font-weight:bold} UL.toc LI UL A (color-.white) UL.toc A:active, UL.toc A.select (color:white; background:blue) UL.toc .over (color:red) /* Цвет выделения */ UL.toc UL P (margin-top:0; margin-bottom:0} </STYLE> <STYLE TYPE="text/JavaScript"> /* Метод отображения списка в Netscape Navigator 4.0. */ /* Определение альтернативного стиля для "UL.toc UL". */ contextual(classes.toe.UL, tags.UL).display = "block"; </STYLE> <BASE TARGET="DEMO”> <SCRIPT LANGUAGE="JavaScript"> // Общий код отображения // Данный метод позволяет писать общий код, который // автоматически отображает или прячет содержание. var curSelection = null; function setstyle(src, toClass) ( // Format the element to the specified class.
Глава 11. Динамические стили 341 if (null != sre) ' . • sre.className = toClass; ) function mouseEnters() { // Проверьте, что элемент не является выделенным и // является якорем. if ((curSelection != event.toElement) && ("A" == event.toElement.tagName)) setStyle(event.toElement,"over"); } function mouseLeaves() ( // Снова проверьте, что элемент не является выделенным и // является якорем. if ((curSelection != event.fromElement) S& ("A" == event.fromElement.tagName)) setStyle(event.fromElement, '"'); } function outlinerf) ( var child = null, el = null; /* Предполагает, что элемент DIV, содержащий дочерние элементы находится сразу же после якоря заголовка. */ switch (event.srcElement.tagName) ( case "A"; el = event.srcElement.parentEiement; child = document.all(event.srcElement.sourceindex + 1]; break; case "LI": el = event.srcElement; child = document.all[event.srcElement.sourceindex + 2]; break; } /* Проверка наличия дочернего элемента и что зто дочерний элемент LI. */ if ((null != child) && ("UL" == child.tagName) S& ("LI" == child.parentEiement.tagName)) ( if == child.className) ( // Collapse the item. child.className = "expanded"; el.className = "open"; ) else ( // Разворачивание элемента. child.className =
342 Часть Ш. Стиль документа и анимация el.className = "closed"; ) ) if ("A" == event.srcEiement.tagName) [ if (null != curSelection) setStyle(curSelection, ; // Сохранение и выделение нового выбора. curSelection - event.srcEiement; setstyle(curSelection, "select”); ) } </SCRIPT> </HEAD> <BODY> <UL CIASS="toc" ONCLICK="outliner ();" ONSELECTSTART=”return false;” ONMOUSEOVER=”mouseEnters();" ONMOUSEOUT="mouseLeaves ();"> • <LI> <A HREF="chl/overview.htm">HTML and CSS Overview</A> <UL> <LI> <A HREF="chl/html40.htm" TITLE=”HTML 4.0"> HTML "4.0"</A> </LI> <LI> <A HREF="chl/css.htm" TITLE="CSS Features'^ CSS Features</A> </LI> <LI> <A HREF="chl/cssp.htm" TITLE="CSS Positioning"> CSS Positioning</A> </LI> <LI> <A HREF="chl/settings.htm" TITLE="System Settings'^ System Settings</A> </LI> </UL> </LI> <LI> <A HREF=”ch2/overview.htm"> Fundamentals of HTML Scripting</A> <UL> <LI> <A HREF="ch2/langs.htm"
Гпава 11. Динамические стили 343 TITLE="Supported Languages'^ Supported Languages</A> </LI> <LI> <A HREF="ch2/guidelns.htm" TITLE="Variable Naming Guidelines"> Naming Conventions</A> </LI> </UL> </LI> <!— Новые варианты могут быть добавлены путем внесения дополнительных элементов списка. —> </UL> • * ' </RODY> </HTML> В данном примере продемонстрировано написание универсального кода, пригодного для многократного использования. Меню полностью инкапсу- лировано на основе таблиц стилей и сценариев, которые непосредственно связаны со списком содержания. Данный пример может быть использован в любом документе без изменений в самом документе или его сценарии. Хотя данная страница плавно деградирует в браузерах низкого уровня, кото- рые не поддерживают таблицы стилей, в страницу введен специальный код для корректного отображения в браузере Netscape Navigator 4.0. В данной версии браузера значение display:попе распознается и дочерние элементы не отображаются. Поскольку Netscape Navigator не поддерживает манипуля- ции динамическими стилями, то список не может быть динамически раз- вернут для отображения вложенных данных. Для корректного отображения в Netscape Navigator в данном документе используется сценарий таблицы стилей JASS. Данная таблица стилей распознается только Netscape Navigator 4.0 и используется для повторного отображения скрытых элементов. Табли- ца стилей JASS подчиняется определенной в CSS таблице стилей в документе. <STYLE TYPE=”text/JavaScript"> /* Определение альтернативного стиля для "UL.toc UL". */ contextual(classes.toe.UL, tags.UL).display = "block"; </STYLE> Данный метод определения таблицы стилей JASS полезен для переключения режимами между воспроизведением браузеров Internet Explorer 4.0 и Netscape Navigator 4.0. Вы можете определить другие стили для применения в Netscape Navigator, использующем JASS. Белее подробную информацию по данному вопросу можно найти на Web-узле компании Netscape (www.netseape.com).
344 Часть ///. Стиль документа и анимация Методы анимации текста Изменение стиля элемента в соответствии е установками таймера позволяет создавать текстовые анимации. Сценарии могут изменять один или большее количество стилей для каждого сигнала таймера. Приведенные ниже два примера демонстрируют изменение внешнего вида элемента с течением времени. Данные примеры могут быть изменены для модификации любых свойств CSS элемента. Изменение внешнего вида документа е помощью таймера полезно для при- влечения внимания к содержащейся в документе информации. Данный ме- тод может быть использован вместо внедрения больших анимированных рисунков в формате GIF. Анимированный текст с несколькими строками сценария всегда обеспечивает более высокую производительность, чем за- грузка рисунков GIF, которые служат той же цели. Как уже было замечено, данные примеры не работают в браузерах низкого уровня, но вы можете легко добавить код, проверяющий, что браузер запус- тил страницу, а также выполняющий запуск или остановку таймера, если браузер пользователя не является браузером Internet Explorer 4.0. Эластичный текст Приведенный ниже пример демонстрирует изменение свойства CSS letter-spacing определенного элемента в ответ на сигналы таймера. Дан- ный метод может быть использован для добавления интересных эффектов в заголовки или другие элементы содержания. <HTML> <HEAD> <TITLE> Эластичный текст </TITLE> ’ । <SCRIPT LANGUAGE="JavaScript"> // Массив значений размеров var sizes = new ArrayC'Opx", "Ipx", "2px", "4px", "8px"); sizes.pos = 0; function rubberBand() ( var el = document.all.elastic; if (null == el.direction) el.direction = 1; else if ((sizes.pos > sizes.length — 2) |I (0 == sizes.pos)) el.direction *= -1; el.style.letterspacing = sizes[sizes.pos += el.direction]; ) </SCRIPT> </HEAD>
Глава / /. Динамические стили 345 CBODY ONLOAD=”window.tm = setinterval(’rubberBand() 1, 100);" ONUNLOAD="clearInterval(window.tm);"> <H1 ID="elastic" ALIGN="Center">This Is Elastic Text</Hl> </BODY> </HTML> Пульсирующие элементы Приведенный ниже код расширяет возможности предыдущего примера пу- тем ежесекундного изменения нескольких элементов (период изменения показаний таймера) и посредством использования нового класса для опре- деления альтернативного стиля: <HTML> <HEAD> <TITLE> Пульсирующие кнопки </TITLE> CSTYLE TYPE="text/css"> .pulsate (letter-spacing:2; font-weight:bolder; color:blue) </STYLE> <SCRIPT LANGUAGE="’JavaScript"> function pulsate!) ( // Получение всех элементов с именем "pulsate" или ID. var рЕ1 = document.all.pulsate; if (null == pEl.length) // Только один элемент pEl.className = pEl.className = "pulsate” ? "pulsate"; else // Повторение всех пульсирующих» элементов. for (var i = 0; i < pEl.length; i++) with (pEl[i]) className = className == "pulsate" ? "pulsate"; ) C/SCRIPT> </HEAD> CBODY ONLOAD=”window.tm = setinterval(’pulsate()’, 1500);” ONUNLOAD="clearInterval(window.tm) ; "> CINPUT TYPE=BUTTON NAME="pulsate" VALUE="Click Me!"> CINPUT TYPE=BUTTON NAME="pulsate" VALUE="Click Me Too!”> ( c/BODY> C/HTML>
HSSHW1’'"'' Глава 12 Динамическое позиционирование Каскадные таблицы стилей (Cascading Style Sheets, CSS) позволяют опреде- лить точное положение HTML-элементов. Динамическое позиционирование использует объектную модель для доступа и манипулирования положением элементов в документе с помощью объектной модели CSS. Возможность точного позиционирования элементов с помощью HTML впер- вые появилась в Internet Explorer 3.0 посредством элемента HTML Layout. Элемент HTML Layout был разработан как элемент ActiveX, который интер- претировал раннюю версию синтаксиса позиционирования CSS. Элемент ActiveX был внедрен в браузер временно на период доработки синтаксиса позиционирования консорциумом W3C (World Wide Web Consortium). В конце I996 года синтаксис был одобрен в рабочем проекте консорциума "CSS Positioning (CSS-Р)" ("Позиционирование CSS (CSS-Р)”). Скотт Фурман, представитель компании Netscape, и автор этой книги в качестве представителя компании Microsoft, совместно выполнили данный проект. Браузеры Internet Explorer 4.0 и Netscape Navigator 4.0 поддерживают рабо- чий проект CSS-Р для позиционирования элементов, так что страницы, соз- данные с использованием CSS-Р, практически одинаково отображаются в обоих браузерах. Однако существует ряд мелких отличий между браузерами, касающихся точного воспроизведения размера и положения элемента. Рабочий проект CSS-Р устанавливает синтаксис CSS для определения ис- ходного положения элементов на странице. Этот проект не устанавливает модель сценариев. Объектная модель, представленная в Netscape Navigator 4.0 для перемещения позиционированных элементов отличается от модели, представленной в Internet Explorer 4.0. Модель Netscape Navigator предостав- ляет только часть функциональных возможностей, доступных в Internet Explorer. Рабочий проект CSS-Р определяет три типа позиционирования: статическое, абсолютное и относительное. Статическое позиционирование используется
Глава 12. Динамическое позиционирование 347 по умолчанию и соответствует традиционному способу размещения HTML- документов. При использовании абсолютного позиционирования элемент изымается из нормального потока документа и размещается в соответствии с родительской системой координат. Абсолютно позиционированный элемент не оказывает влияния на окружающие его элементы в документе. При ис- пользовании относительного позиционирования элемент находится в потоке документа и размещается относительно его нормального положения в пото- ке. При изменении размера документа элемент, позиционированный отно- сительно, может перемещаться и изменять свою форму в результате пере- форматирования документа. Абсолютно и относительно позиционирован- ные элементы создают системы координат для позиционирования возможных дочерних элементов. В данной главе представлены свойства CSS-Р и модель сценариев для управления местоположением элементов и рассмотрены следующие темы: □ Позиционирование CSS. В данном разделе обсуждаются улучшения в CSS для управления положением элементов. Позиционирование CSS поддер- живает два новых способа позиционирования элемента: относительный, когда положение элемента устанавливается относительно нормального положения элемента в потоке документа, и абсолютный, когда элемент перемещается за пределы потока и размещается с абсолютной точностью. В этом разделе вводятся свойства позиционирования CSS и отношения между двумя моделями позиционирования. □ Программирование позиционирования CSS. Свойствами позиционирова- ния CSS можно динамически манипулировать с помощью объектной мо- дели динамического HTML. Показано, как анимировать текст и графику с помощью таймеров и как реагировать на действия пользователя для ак- тивизации операций перемещения с помощью мыши. □ Контекст воспроизведения. В данном разделе продемонстрирована взаи- мосвязь между положением элемента и окружающими его элементами, а также вводятся отношения воспроизведения между элементами, которые устанавливают методику определения положения элемента в документе. Позиционирование CSS Рабочий проект CSS-Р определяет расширения таблиц стилей для обеспече- ния дополнительных возможностей управления HTML-элементами. Абсо- лютное и относительное позиционирование позволяет Web-разработчику точно управлять положением и размером элемента, а также проводить на- ложение элементов. Совместное использование^этих нововведений вместе с программированием сценариев позволяет осуществлять анимацию элемен- тов. В данном разделе представлено краткое введение в методы использова- ния новых возможностей позиционирования CSS.
348 Часть III. Стиль документа и анимация Свойства позиционирования CSS Рабочий проект CSS-Р определяет новые свойства CSS, которые поддержи- ваются браузерами Internet Explorer 4.0 и Netscape Navigator 4.0. В табл. 12.1 перечислены данные свойства. Значения по умолчанию для каждого свойст- ва выделено полужирным начертанием. Таблица 12.1. Свойства позиционирования CSS Свойство Допустимые величины Область применения Описание position static I absolute | relative Все элементы Определяет, будет ли эле- мент помещен в поток (статическое позициониро- вание), относительно его нормального положения в потоке (относительное по- зиционирование) или за пределами потока (абсо- лютное позиционирова- ние) top, left auto | <length> | <percentage> Все элементы со значе- нием атрибута position, равным значению absolute или relative Определяет верхнее и левое положения эле- мента относительно его родительского контекста воспроизведения width, height auto | <length> I <percentage> Все элементы блока, за- меняемые элементы (на- пример, элементы IMG и внутренние элементы управления) и элементы со значением атрибута position равным absolute Определяет ширину и высоту элемента. Про- центные значения уста- новлены относительно ро- дительского контекста вос- произведения clip auto| rect (top right bottom left) Все элементы со значе- нием атрибута position равным absolute или relative Определяет область вы- резки элемента z-index auto I number Все элементы со значе- нием атрибута position равным absolute или relative Определяет положение элемента, на который на- кладываются другие эле- менты или который на- кладывается на другие элементы
Гпава 12. Динамическое позиционирование 349 Таблица 12.1 (окончание) Свойство Допустимые величины Применяется к Описание visibility inherit I visible | hidden Все элементы Определяет область ви- димости элемента. Спря- танный элемент не удаля- ется из потока документа overflow visible | hidden | auto | scroll Все элементы со значе- нием атрибута position равным absolute, все элементы блоков Определяет отображение полос прокрутки, если содержание документа не помещается в элементе Позиционируемые элементы Традиционно, большинство элементов в HMTL позиционируются относи- тельно предыдущих элементов в потоке документа. Исключением из этого правила является возможность выравнивать изображения и другие объекты и обтекать их текстом. Позиционирование CSS позволяет позиционировать элементы в отдельной рамке отдельно от потока документа или за предела- ми их обычного положения в документе. Позиционирование CSS допускает наложение элементов и предоставляет Web-разработчикам большие возмож- ности управления размещением элементов по сравнению с доступными ранее. Как упоминалось выше, свойство CSS position может принимать одно из трех значений: static (статическое), absolute (абсолютное) или relative (относительное). Статическое позиционирование по умолчанию не оказыва- ет влияния на традиционную схему размещения HTML-документа. Относительное позиционирование используется для смещения документа за пределы его нормального положения в потоке документа. Установка значе- ния relative для элемента position не изменяет размещение элемента, но если вы также установили значение свойства top или left, то элемент сме- щается от своего нормального положения в потоке. В тексте на рис. 12.1 одно слово сдвинуто на Ю пикселов по горизонтальной и вертикальной осям. Обратите внимание, что остальная часть документа расположена так, как будто данное слово не было сдвинуто. Относительное позиционирова- ние особенно полезно при создании анимированных элементов, таких как изображения, рядом с их нормальными положениями в документе. Абсолютное позиционирование используется для определения фиксирован- ного положения элемента за пределами потока документа. В тексте на рис. 12.2 одно слово позиционировано в верхнем левом углу окна браузера. Обратите внимание на отсутствие интервала.
350 Часть III. Стиль документа и анимация Q Relative Positioning Microsoft Internet Explorer f> E-i View . fio .. Fj*o^*-s. . ИФ. Q Absolute Positioning • Microsoft Internet Explorer S31 tffew Цо Favorites latent can either be positioned relative to its location m the document’s flow or be positioned at an location in the document. An element can either be positioned . . to its location in the document's flow or be positioned at an *- absolute location in the document. Рис. 12.1. Элемент, позиционированный относительно I MytompUw Рис. 12.2. Абсолютно позиционированный документ Поскольку абсолютно позиционированные элементы размешаются за пре- делами потока, то положение элемента внутри источника документа стано- вится несущественно. Элемент должен быть помещен в источнике в том по- ложении, которое обеспечит приемлемый результат в браузерах низкого уровня. Такие браузеры не поддерживают новых возможностей позициони- рования и поэтому располагают изображение в потоке документа. В браузере Internet Explorer 4.0 все элементы в теле документа поддерживают статическое и динамическое позиционирование. Однако абсолютное позицио- нирование поддерживают только те элементы, которые перечислены ниже: □ Applet □ Fieldset 0 Input □ Span О Button □ IFrame 0 Object 0 Table □ DIV 0 IMG 0 Select □ TextArea Для абсолютного позиционирования текста следует использовать элемент Span или div. Элементы span и div взаимозаменяемы, но при выборе одного из них следует учесть предполагаемый внешний вид элемента в браузере низкого уровня. Если разрыв требуется и до и после текста, то следует ис- пользовать элемент div. Если текст Может находиться в параграфе, то следу- ет использовать элемент Span. Отображение документа всегда следует прове- рять на всех платформах, которые будут использованы для его просмотра, для гарантии его адекватного отображения. Определение системы координат Каждый элемент, который позиционирован абсолютно или относительно, должен быть позиционирован относительно другого элемента или положе- ния в документе. Точка, относительно которой сдвинут документ, называет- ся корнем (root) системы координат элемента. По умолчанию, местоположе- ние корня относительно позиционированных элементов определяется на
Глава 12. Динамическое позиционирование 351 основе его местоположения в потоке документа. Поэтому если документ переформатируется, то корень системы координат, а также дочерние эле- менты внутри данной системы координат будут смещены. Абсолютно позиционированные элементы размещаются относительно сис- темы координат, в которой находится элемент. Верхний левый угол доку- мента определяет систему координат по умолчанию для абсолютно пози- ционированных элементов. Независимо от того, позиционирован элемент относительно или абсолютно, новая система координат определена для всех находящихся в нем элементов. Свойства размера и положения Если элемент позиционирован абсолютно или относительно, его свойства top и left определяют смещение элемента от верхнего левого угла системы коор- динат. Свойства width и height определяют физическую ширину и высоту элемента при его воспроизведении на экране. Если вы используете относи- тельные размеры, то свойства width и height интерпретируются относительно размера элемента, определяющего систему координат. Свойства top, left, width и height могут быть определены в процентном отношении или других единицах (например, точках, пиксе- лах и епт), определенных CSS. На рис. 12.3 показаны свойства top, left, width и height двух вложенных элементов div. TOPI — свойство первого элемента DIV top=50 (пикселов) LEFT1 — свойство первого элемента DIV left=50 (пикселов) ТОР2 — свойство вложенного элемента DIV top=100 (пикселов) LEFT2 — свойство вложенного элемента DIV left=40 (пикселов) Positioning end Coordinate Systems Mier... ; i Цо Fjvcriles Цф \ ТОР1 \ LEFT1 W1 Н1 TOP2 LEFT2 Абсолютно позиционированный элемент DIV W2 Н2 Вложенный абсолютно позиционированный элемент DIV Рис. 12.3. Вложенные системы координат $ Автоматическая установка размера Для свойств top и left значение по умолчанию, равное auto, является нор- мальным положением элемента в потоке. Когда значения свойств top и left равны auto, то относительно позиционированной элемент отображается так же, как и статический элемент, а абсолютно позиционированный элемент отображается за пределами потока, но связан с положением, которое бы он
352 Часть III. Стиль документа и анимация занимал, будучи статическим элементом. Если свойства width и height опу- щены, то размер элемента устанавливается автоматически на основе его со- держания. Свойство visibility По умолчанию элемент видим, если отображается его родительский эле- мент. Например, скрытие элемента Body путем установки значения hidden для свойства visibility прячет все содержание документа. Вы можете из- менить данное поведение путем явной установки значений hidden или visible для свойства visibility вместо установленного по умолчанию inherit. Если значение свойства visibility установлено явно, то элемент не учитывает любые наследованные значения и будет, соответственно, отобра- жен или скрыт. Свойство z-index Свойство z-index определяет графический z-порядок, или перекрытие эле- ментов по отношению к другим элементам. Каждая координатная система определяет новое z-пространство для воспроизводимых элементов, таким образом обеспечивая иерархический z-порядок. Например, если элемент div абсолютно позиционирован поверх тела документа, то содержание элемента div не может появиться в теле документа после текста. Все элементы внутри элемента div могут быть только позиционированы в системе координат эле- мента DIV. По умолчанию все элементы, определяющие систему координат, включая элемент Body, позиционированы со значением z-index, равным 0. Другие элементы могут быть позиционированы после текста путем установки отри- цательного значения z-index. Для элементов, значения z-index которых не установлены, значения z-index неявно назначаются в соответствии с их положением в исходном документе. Поэтому элемент, который помещен в данный документ позже, помещается до всех элементов, позициони- рованных ранее. Области вырезки Каждый абсолютно позиционированный элемент имеет связанную с ним область вырезки, назначение которой заключается в определении части до- кумента, доступной для отображения элемента и его содержания. Все, что находится за пределами данной области, отбрасывается и не отображается документом. Представим себе непрозрачный лист бумаги, который закрывает физиче- скую область абсолютно позиционированного элемента. В данном листе бу- маги имеется прямоугольный вырез, определяющий видимую область эле-
Глава 12. Динамическое позиционирование 353 мента. Все, что не помещается в данном вырезе, отбрасывается и становится невидимым. На рис. 12.4 показано использование областей вырезки. В левой части ри- сунка показана страница без вырезки. Больший по размеру прямоугольник представляет собой элемент div. Меньший прямоугольник находится внутри элемента div, но абсолютно позиционирован за пределами элемента div. В правой части рисунка показан тот же документ после выполнения вырезки. Clipping the Contents - Miciosoll Into... ИЕЁ1 E3 £3 Clipping lhe Contents • MiciosoH Into... . i Eile ЕЛ Уии fio Fgvofiles Help The clip value can be used to hide contents that exist above and below this DIV Notice the borders and the element positioned beyond the nght border Contents can continue beyond the specified clipping region. ffhis element is ^absolutely positioned with respect to the DIV element t exist aoove ano ow this DIV Notice borders and the ment positioned /ond the nght rder. Contents can itinue beyond the tcified dinning Рис. 12.4. Элемент div с частью содержания за его пределами без вырезки (слева) и с прямоугольной вырезкой (справа) Значение по умолчанию для свойства clip равно auto, что обусловливает отсутствие вырезки документа. Вы можете установить значение свойства clip равным прямоугольному вырезу: cliptrect(top right bottom left) Установки top, right, bottom и left определяют прямоугольник вырезки по отношению к абсолютно позиционированному верхнему левому углу эле- мента. Любой из данных четырех параметров может быть установлен рав- ным любой длине CSS или значению auto для запрещения вырезки в этом направлении. Если свойства top и left равны отрицательным значениям, то элементы сверху и слева от абсолютно позиционированного элемента могут быть включены в область вырезки. Свойство overflow Свойство overflow управляет обработкой содержания, которое выходит за пределы физического размера элемента. Свойство overflow принимает одно из четырех значений: visible, hidden, auto и scroll. Если значение overflow
354 Часть III. Стиль документа и анимация равно visible, то будет отображаться все содержание документа, даже со- держание за пределами установленной высоты (height) и ширины (width) элемента. Если значение overflow равно hidden, то будет отображаться толь- ко содержимое внутри области элемента, определенной значениями свойств height и width. Содержание элемента за пределами установленных границ отображаться не будет. Значения auto и scroll используются для добавления полос прокрутки, если содержание превышает область, ограниченную значениями height и width.’ Полосы прокрутки могут быть добавлены в любой абсолютно позициониро- ванный элемент, в элементы div с определенной высотой и любой элемент, который поддерживает свойство float каскадных таблиц стилей CSS. Если значение параметра overflow равно scroll, то всегда будут отображены по- лосы прокрутки. Если значение равно auto, то полосы прокрутки будут ото- бражаться только при необходимости. Приведенный ниже документ демонстрирует создание маркера полосы про- крутки: . - ... <HTML> ’ . " . <HEAD> <TITLE> Маркер полосы прокрутки </TITLE> </HEAD> <BODY> <DIV STYLE=”ove r flow .-scroll; float: left; width:120pt; height:120pt"> <Hl>Scrolling Sidebar</Hl> <P>This text appears in a scrolling window that is floating to the left of the main contents.</P> </DIV> <P>These contents appear to the right of the scrolling DIV element. </BODY> </HTML> Данный документ показан на рис. 12.5. Если для элемента определены полосы прокрутки, то они автоматически расширяются для включения абсолютно позиционированных дочерних эле- ментов. Данное расширение гарантирует, что пользователю будут доступны все абсолютно позиционированные дочерние элементы. Вы можете создать полностью доступные формы и сложные схемы размещения. Исключение в данном случае составляет любой элемент, который позиционирован отрица- тельно. Полосы прокрутки никогда не используются в пространстве отрица- тельных координат. Если полосы прокрутки отображаются с помощью свойства overflow, то вырезка не влияет на абсолютно позиционированные дочерние элементы.
Глава 12. Динамическое позиционирование 355 El Scrolling Sidebar - Microsoft Internet Explorer E31 'Йе yiew. Во ТдаоЛм' Цф Пользователь может, тем не менее, прокручивать их, и они будут доступны. Напротив, если область вырезки не включает в себя целиком весь элемент с полосами прокрутки, то он будет усечен. Данное правило проил- люстрировано на рис. 12.6. Справа абсолютно позиционированный эле- мент не виден, поскольку он нахо- дится внутри элемента div с поло- сами прокрутки. JaThese contents appear Scrolling gto the right of the S scrolling DIV element This text appears in a scrolling window that is Eoatine to the left of the, Рис. 12.5. Документ с маркером полосы прокрутки Clippint) (he Contents Microsoft Into Q Clipping (he Conlents - Miciosofl Into... HP1E3 '•ЕШо£<4 yiew Цо FflvociM ftelr i exist auuve шкз ow this DIV Notice borders and the ment positioned fond the right rder Contents can itmue beyond the icified cliooina postht respei DIV e r exist auuve aiu ow this DIV >tice the borders i the element sitioned beyond right border ntents can гооаайх El Рис. 12.6. Слева изображен экран с областью вырезки и без полос прокрутки. Справа — тот же элемент с полосами прокрутки Примечание J Относительно позиционированные элементы не влияют на полосу прокрутки. При расчете полосы прокрутки учитывается только исходное пространство элемента а потоке, поскольку местоположение относительно позиционирован- ного элемента в документе является его положением в потоке, а смещение просто определяет точку выаода элемента. Более того, относительно позицио- нированные элементы наиболее часто используются для анимации. Включение данных элементов в расчет полосы прокрутки будет влиять на анимацию На- пример, надо обеспечить прокручивание тексте за пределы правого края экра- на. Отсутствует полоса прокрутки, которая позволит пользователю прокручи- вать текст обратно в область просмотра.
356 Часть III. Стиль документа и анимация Программирование позиционирования CSS Любой стандартный элемент с абсолютным или относительным позициони- рованием может быть динамически перемещен, а его размер может быть изменен с помощью сценария. Данный метод позволяет осуществлять ани- мацию позиционированных элементов путем изменения положения, изме- нения размера и динамического изменения области вырезки элемента. Ма- нипулирование положением элемента и областью вырезки осуществляется посредством объектных моделей таблицы стилей. Свойство position CSS в браузере Internet Explorer 4.0 допускает только чте- ние. Для перемещения с помощью сценария элемент при создании должен быть позиционирован или относительно или абсолютно, независимо от то- го, был ли он создан из исходного кода или вставлен посредством динами- ческого содержания, что описывается в главе 13. Данное правило справед- ливо, даже если таблица стилей модифицируется с помощью объектной мо- дели CSS после воспроизведения элемента. Свойства позиционирования CSS Каждое свойство размера или положения CSS представлено набором свойств, которые делают более удобным доступ к нему и манипулирование его размером и положением. Подобно другим свойствам CSS свойства юр, left, width И height представлены ПОСреДСТВОМ СВОЙСТВЭ style элемента. Данные свойства являются строками и возвращают значения в определен- ных единицах. Например, элемент со значением top равным 20 пунктов воз- вращает 20pt. Манипулирование данной строкой может быть очень сложным, особенно если код пытается изменить положение элемента на экране. Поэтому кроме свойств со строковыми значениями, представлены свойства: posTop, posLeft, poswidth и posHeight. Если значение top является строкой 20pt, то значение розТор равно числу 20. Числовым значением можно манипулировать непо- средственно. Поскольку основной единицей измерения в объектной модели динамиче- ского HTML является пиксел, то представлены четыре дополнительных свойства, которые возвращают значения размера и положения, преобразо- ванные в пикселы: pixeiTop, pixeiLeft, pixelwidth и pixeineight. Установка значения одного из свойств вызывает преобразование значения в исходно определенные единицы, когда оно представляется посредством значения роз* и свойств со строковыми значениями. Эти двенадцать свойств таблиц стилей определяются при анализе документа. В разделе данной главы "Контекст воспроизведения" описываются свойства для доступа к размеру и положению отображаемого элемента, позволяющие
Гпава 12. Динамическое позиционирование 357 создавать совершенно индивидуальную схему размещения элементов, в ко- торой сценарий управляет воспроизведением всего документа. Абсолютное позиционирование Приведенные ниже примеры демонстрируют манипулирование абсолютно позиционированными элементами. Абсолютно позиционированные элемен- ты используются для активизации операций перемещения с помощью мы- ши для размещения элементов в определенных точках на экране. Статический логотип Используя свойство CSS background, можно установить положение фоно- вого изображения для создания статического логотипа, который нс будет прокручиваться вместе с окном. Приведенный ниже код закрепляет изобра- жение в нижнем правом углу окна клиента: BODY (background:URL(logo.gif) fixed bottom right no-repeat) Используя только CSS, нельзя фиксировать местоположение элементов так, чтобы они не прокручивались вместе с окном, кроме фоновых изображений. Однако этого можно достичь, используя абсолютное позиционирование и простой сценарий. Следующий пример создает статический текст, который всегда находится в фиксированном положении относительно верхнего ле- вого угла текущего окна. Для того чтобы перемещать элемент при прокру- чивании документа, код, позиционирующий текст, отслеживает события onscroll. Текстовый логотип в данном примере подобен телевизионному логотипу, ко- торый иногда появляется во время телевизионных передач. Логотип отобража- ется постоянно, но код можно легко изменить, чтобы логотип появлялся и исчезал на экране с определенной периодичностью, с помощью таймера по- переменно устанавливая для свойства display значения попе или block. (Если в таблице глобальных стилей для свойства display элемента установле- но значение попе, то сценарий не может заменить это значение на пустую строку для отображения элемента, а должен явно установить для свойства display значение block или inline, соответствующее данному элементу). Приведенный ниже код является простейшей реализацией текстового лого- типа. Он помещает логотип в верхний левый угол экрана, для чего требуется только отслеживать события scroll и не надо вычислять положение логоти- па. Для отображения логотипа в любом из других углов следует также от- слеживать событие onresize. Когда пользователь изменяет размер страницы, положение логотипа должно быть снова рассчитано на основе нового раз- мера окна, также следует учесть ширину и высоту самого элемента.
358 Часть HL Стиль документа и анимация <HTML> <HEAD> <TITLE> Статический логотип </TITLE> <SCRIPT LANGUAGE”"JavaScript"> ' function resetLogof) { document.all.Logo.style.posTop = document.body.scrollTop; document.all.Logo.style.posLeft = document.body.scrol1Left; } </SCRIPT> </HEAD> <BODY ONSCROLL="resetLogo()"> <DIV ID=”Logo" SRC="logo.gif" STYLE="position:absolute; z-index:-l; top:0px; left:0px; color:gray"> Inside DHTML , </DIV> <P>Add HTML document here.</P> </BODY> </HTML> Логотип лучше смотрится с ярким текстом. В противном случае он может затенять содержание страницы. Логотип может быть помещен за содержа- нием или вверху над содержанием документа путем установки следующих значений свойства z-index. □ -1 устанавливает положение логотипа на заднем фоне содержания. □ 1 (по умолчанию) определяет положение логотипа над содержанием. Логотип может находиться за другими элементами ниже в зависимости от значения свойства z-index других элементов. Прыгающий мяч Этот пример иллюстрирует взаимоотношения между свойствами положения и размером окна. Приведенный ниже код является расширением примера со статическим логотипом. Изображение перемешается по экрану и выпрыги- вает за границы экрана: <нтмь> <HEAD> <TITLE> Прыгающий мяч </TITLE> <SCRIPT LANGUAGE”"JavaScript"> var x = 0; var у = 0; var offsetx = 4; var offsety =4;
Гпава 12. Динамическое позиционирование 359 function bouncelt() ( var el = document.a11.bounce; x += offsetx; у += offsety; if ((x + el.offsetwidth >= document.body.clientwidth + document.body.scrollLeft) || (x <= document.body.scrollLeft)) ( offsetx = -offsetx; if (x <= document.body.scrollLeft) x = document.body.scrollLeft; else x = document.body.clientwidth — el.offsetwidth + document.body.scrollLeft; } if ((y + el.offsetWidth >= document.body.clientHeight + document.body.scrollTop) II (y <= document.body.scrollTop)) ( offsety = -offsety; if (y <= document.body.scrollTop) у - document.body.scrollTop; else у = document.body.clientHeight — el.offsetHeight + document.body.scrollTop; ) el.style.posLeft = x; el.style.posTop = y; ... } </SCRIPT> </HEAD> <BODY ONLOAD="window, tm = setinterval('bouncelt()', 10);" ONUNLOAD=”clearInterval(window.tm);"> <IMG SRC="ball.gif” ID=”bounce" STYLE="position:absolute; top:0; left:0; z-index:-l"> <Hl>Bouncing Ball</Hl> <P>The ball bounces around and around under the text.</P> <P>This page works even if you resize or scroll the window.</P> <P>This page takes advantage of: <UL> <LI>Absolute positioning <LI>Moving elements based on the timer <LI>Z-indexing <LI>Client size and scrollbar position properties </UL> </BODY> </HTML>
360 Часть III. Стиль документа и анимация Движением изображения по экрану управляет таймер. Изображение пере- мещается за текстом, так как установлено минимальное значение свойства z-index. Данный пример анимирует изображение, но также может быть анимирован любой код HTML на экране. Например, вы можете заменить данное изображение элементом div, указать ширину элемента div, добавить HTML-содержание и анимировать его. Эффекты исчезновения и появления Программирование свойства CSS clip позволяет создавать интересные эф- фекты появления и исчезновения. Эффект появления заключается в том, что элемент постепенно выводится на экран, начиная появляться с одного края. Эффект исчезновения заключается в постепенном удалении элемента с экрана аналогичным образом. Приведенный ниже документ содержит функцию создания различных вертикальных и iоризонтальпых эффектов исчсзновеиия/появления для абсолютно позиционированного элемента, а также кнопки для тестирования этих эффектов: <HTML> <HEAD> <TITLE> Эффекты возникновения/удаления </TITLE> <STYLE TYPE=”text/css"> BODY (text-align:center) Dwipe (position:absolute; top:200pt; left:4O%; clip:rect(O 100% 100% 0); border:2pt navy solid; width: lOOpt; background:wh.ite) P (margin-top:Opt; margin-bottom:Opt) INPUT {width:100%) </STYLE> <SCRIPT LANGUAGE="JavaScript" ID=”WipeEffects"> function wipe(direction) ( var el = document.a11.wipe; /* Второй аргумент необязателен и определяет появление или исчезновение элемента. По умолчанию воспроизводится эффект появления. */ var into = true; if (arguments[1] != null) into = arguments[1]; if (null == el.init) ( // Инициализация эффекта. //Вся информация появления/исчезновения хранится в этом элементе, el.init = true; el.clipTop = 0; el.clipRight = 0; el.clipBottom = 0;
Гпава 12. Динамическое позиционирование 361 el.clipLeft = О el.inc = 4; if (into) // Установка эффекта появления, switch (direction) { case "clipBottom": el.clipRight = "100%"; el.size = el.offsetHeight; break; case'"clipRight”: el.clipBottom = "100%”; el.size = el.offsetwidth; break; case "clipTop": el.clipBottom = "100%"; el.clipRight = "100%”; el.clipTop = el.offsetHeight; el.inc *= -1; el.size = 0; break; case "clipLeft": el.clipBottom = "100%"; el.clipRight - "100%"; el.clipLeft = el.offsetwidth; el.inc *- -1; el.size = 0; break; ) else // Установка эффекта исчезновения, switch (direction) ( case "clipBottom": el.clipRight = ”100%"; el.clipBottom = el.offsetHeight; el.size = 0; el.inc *= -1; break; case "clipRight": el.clipBottom = "100%”; el.clipRight = el.offsetwidth; el.size = 0; el.inc *= -1; break; case "clipTop": el.clipBottom - "100%"; el.clipRight - "100%"; el.clipHeight = el.offsetHeight;
362 Часть III. Стиль документа и анимация el.size = el.offsetHeight; break; case "clipLeft": el.clipBottom = "100%"; el.clipRight = "100%"; el.clipLeft = 0; el.size = el.offsetwidth; break; ) // Увеличение выреза. ,el[direction] += el.inc; // Установка выреза. el. style.clip = "rectf + el.clipTop + " " + el.clipRight + " " 4- el.clipBottom 4- " " + el.clipLeft + "); // Проверка завершения. if (((el.size >= el[direction)) && (el.inc >0)) II ((el[direction] >= 0) && (el.inc < 0))) setTimeout ("wipe (1 " 4- direction + ”4- into 4- 10); else el.init = null; ) c/SCRIPT> C/HEAD> , . CBODY> cHl>Wipe Effectsc/Hl> cP STYLE=“padding-bottom:5pt"> CINPUT TYPE=BUTTON STYLE="width:260pt" VALUE="Display" ONCLICK" "document.all.wipe.style.clip=’rect(0 100% 100% 0)'"> CFIELDSET STYLE="width:130pt"> CLEGEND>Wipe-In Effects</LEGEND> CPXINPUT TYPE=BUTTON VALUE=”Wipe to Bottom" ONCLICK="wipe('clipBottom')> CPXINPUT TYPE=BUTTON VALUE="Wipe to Right" ONCLICK="wipe(’clipRight')> CPXINPUT TYPE=BUTTON VALUE="Wipe to Top" ONCLICK="wipe(clipTop')> CPXINPUT TYPE=BUTTON VALUE="Wipe to Left" ONCLICK="wipe('clipLeft)> C/FIELDSET> CFIELDSET STYLE="width:130pt"> CLEGEND>Wipe-Out Effects</LEGEND>
Гпава 12. Динамическое позиционирование 363 <PXINPUT TYPE=BUTTON VALUE="Wipe from Bottom" ONCLICK="wipe('clipBottom’, false)"> <PXINPUT TYPE=BUTTON VALUE="Wipe from Right" ONCLICK="wipe(1clipRight’, false)"> <PXINPUT TYPE=BUTTON VALUE="Wipe from Top" ONCLICK="wipe('clipTop', false)"> <PXINPUT TYPE=BUTTON VALUE="Wipe from Left" ONCLICK="wipe('clipLeft', false)"> </FIELDSET> <DIV ID=wipe> <P>Home <P>News <P>Info <P>About <P>Demo </DIV> </BODY> </HTML> . ' Создание всплывающих меню Используя абсолютное позиционирование можно создать меню, которые выводятся на экран, когда пользователь щелкает мышью по ключевому сло- ву или строке меню, определенной посредством HTML. Вы можете расши- рить приведенный ниже код, который создает разворачиваемые меню адре- сов URL для использования в своих документах. Эти всплывающие меню могут быть легко расширены путем добавления эффектов появле- ния/исчезновения, которые содержатся в предыдущем коде. <HTML> <HEAD> <TITLE> Всплывающие меню </TITLE> <STYLE TYPE="text/css"> /* Устанавливает всплывание меню слева от текста. */ #menu {float:left; width:50pt; background:lightgrey; border:2px white outset; cursor:default} /* В исходном состоянии меню будут скрыты. */ #menu .popup {position:absolute; display:none; background:lightgrey; border:2px white outset; width:135pt; margin:2pt) #menu P {margin-top:Opt; margin-bottom:Opt) .over {color:navy; font-weight:bold)» </STYLE? <SCRIPT LANGUAGE^'JavaScript"? var curPop = null;
364 Часть III. Стиль документа и анимация function clearCurrent() { // Скрытие всплывающего меню, которое отображается в данный момент, if (null 1= curPop) curPop.style.display = curPop = null; ) function popup() { var el = event.srcElement; clearCurrent(); // Отображение новой команды меню. if (("Р” == el.tagName) && ("menu" = el.parentEiement.id)) ( // Размещение и отображение всплывающего меню. > var elpop = document.all[el.sourceindex t 1]; elpop.style.pixelLeft = document.all.menu.offsetLeft + document.all.menu.offsetwidth - 7; elpop.style.pixelTop = el.offsetTop + document.all.menu.of fsetTop; elpop.style.display = "block"; curPop = elpop; ) event.cancelBubble = true; ) function highlight() ( // Выделение команд меню. if (null != event.fromElement) if ({event.fromElement.tagName == "P") && {event.fromElement.parentEiement.id == "menu"}) event.fromElement.className = if {null != event.toElement) if ((event.toElement.tagName == "P") && (event.toElement.parentEiement.id == "menu”)) • event.toElement.className = "over"; } </SCRIPT> </HEAD> <BODY ONCLICK="clearCurrent()"> <Hl>Menu Example</Hl> <DIV ID="menu" ONCLICK="popup()" ONMOUSEOVER=”high.light()" ONMOUSEOUT="highlight()"> <P>Navigate <DIV CLASS="popup"> <P><A HREF="home.htm">Home</A>
Гпава 12. Динамическое позиционирование 365 <РХА HREF="insideDHTML.htm">Inside DHTML Information </А> <Р><А HREF="tip.htm">Tip of the Week</A> </DIV> <P>News <DIV CLASS="popup"> <P><A HREF="headlines.htm”>Headlines<7A> <P><A HREF="internet.htm">lnternet News</A> <PXA HREF="rumors.htm">Rumor Mill</A> </DIV> </DIV> <P>Click on a menu option in the box on the left.</P> </BODY> </HTML> Добавление возможности перемещения Комбинируя абсолютное позиционирование с событиями мыши, можно моделировать перемещение элементов с помощью мыши. Для добавления поддержки перемещения элементов с помощью мыши можно написать сце- нарий, который ищет атрибут dragEnabled во всех элементах. Сценарий в приведенном ниже коде автоматически обрабатывает перемещения всех элементов, которые имеют данный атрибут, включая вложенные позицио- нированные элементы, так что код не требуется изменять при каждом до- бавлении элемента, доступного для перемещения. Если пользователь удер- живает кнопку мыши нажатой на элементе, для которого установлен атри- бут dragEnabled, а затем перемещает мышь, то элемент будет перемещаться, следуя за перемещением мыши. Другим методом является использование специального имени класса вместо атрибута dragEnabled. <HTML> <HEAD> <TITLE> Добавление поддержки перемещения </TITLE> <SCRIPT LANGUAGE="JavaScript"? // Данный код позволяет перемещать мышью любой // абсолютно позиционированный элемент с индивидуаль- // ним атрибутом dragEnabled. var elDragged = null // Перемещаемый элемент function doMouseMove() ( // Проверяет, нажата ли кнопка мыши и находится ли элемент в // состоянии перемещения. if {(1 == event.button) S& (elDragged 1- null)) ( // Перемещение элемента. // Сохранение положения мыли в документе. var intTop = event.clientY + document.body.scrollTop^
366 Часть III. Стиль документа и анимация var intLeft = event.clientX + document.body.scrollLeft; // Определение элемента, над которым находится указатель мыши. var intLessTop = 0; var intLessLeft = 0; ' var elCurrent = elDragged.offsetParent; while (elCurrent.offsetParent != null), ( intLessTop += elCurrent.offsetTop; intLessLeft += elCurrent.offsetLeft; elCurrent = elCurrent.offsetparent; ) // Установка нового положения. elDragged.style.pixelTop = intTop — intLessTop — elDragged.y; elDragged.style.pixelLeft = intLeft — intLessLeft — elDragged.x; event.returnvalue = false; function checkDrag(elCheck) ( // Проверка того, находится ли указатель мыши над элементом, // который поддерживает перемещение. while (elCheck != null) ( if (null != elCheck.getAttribute("dragEnabled")) return elCheck; elCheck = elCheck.parentElement; I return null; ) function doMouseDown() ( // Сохранение перемещаемого элемента. var elCurrent = checkDrag(event.srcElement); if (null != elCurrent) ( elDragged = elCurrent; // Определение местоположения указателя мыши в элементе. elDragged.х = event.offsetX; elDragged.y = event.offsetY; , var op = event.srcElement; // Поиск действительного местоположения по отношению к // перемещаемому элементу. if ((elDragged != op.offsetParent) 4& (elDragged != event.srcElement)) ( while (op .'= elDragged) { elDragged.x +- op.offsetLeft;
Глава 12. Динамическое позиционирование 367 elDragged.y += op.offsetTop; op = op.offsetParent; ) ) ) function doSelectTest() { // He разрешать выделение текста в перемещаемых элементах, return (null == checkDrag(event.srcElement) && (elDragged!=null)); ) // Связать обработчики событий мыши. document.onmousedown - doMouseDown; document.onmousemove = doMouseMove; // Сброс элемента при отпускании кнопки мыши. document.onmouseup = new Function("elDragged = null;"); document.ondragstart = doSelectTest; document.onselectstart = doSelectTest; </SCRIPT> </HEAD> <BODY> <Hl>Dragging Positioned Elements</Hl> <P>These contents are static and can't be dragged. The following image can be dragged even though it is behind this text. <IMG SRC="ball.gif” dragEnabled STYLE="position:absolute; top:10px; left:20px; cursorihand; z-index:-l;"> <DIV STYLE="position:absolute; top:150px; left:20px; border:2px navy solid; width:100; cursor:hand" dragEnabled> This text can be dragged. </DIV> </BODY> </HTML> Для перемещения элемента рассчитывается новое положение элемента в до- кументе на основе положения мыши в документе. Положение мыши рассчи- тывается путем добавления свойств clientx и clientY в свойства scrollTop и scroiiLeft элемента Body. Положение элемента относительно документа яв- ляется суммой его смещений и смещений воех его предков относительно их относительных контекстов воспроизведения. Свойства смещения обсуждаются ниже в разделе данной главы "Контекст воспроизведений'.
368 Часть III. Стиль документа и анимация Относительное позиционирование Элементы, которые были позиционированы относительно, занимают место в нормальном потоке документа. Данные элементы позиционированы за пределами их положения в нормальном потоке. Основной функций данного элемента является анимация элементов в их корректном положении в доку- менте. Приведенные ниже два примера демонстрируют анимированный текст на экране. Первый пример представляет введение в анимированный текст. Второй пример является более объемным и содержит набор функций для создания серии презентационных эффектов. Пример из раздела данной гла- вы "Выравнивание относительно позиционированных элементов" демонстрирует запуск анимации всех относительно позиционированных элементов из од- ной точки на экране. Плавающий текст Если вы хотите создать текст, выплывающий из-за границы экрана, то он должен быть невидим в исходном состоянии и затем появляться по истече- нии определенного периода времени. Лучшим методом создания текста, вы- плывающего из-за границы экрана, является установка начала текста за пре- делами экрана с определенной отрицательной координатой и последующая установка его исходного положения на основе состояния браузера перед на- чалом анимации. Поскольку динамический HTML не определяет конкретного размера содер- жания и пользователь может прокручивать документ в любом направлении, то исходное положение элемента имеет большое значение. В исходном по- ложении элемента должен быть учтен физический размер экрана и поло- жение полос прокрутки. Приведенный ниже код демонстрирует создание текста, выплывающего из правой границы экрана. В данном примере текст запускается в отрицательном координатном пространстве, так что пользова- тель не может обратиться к тексту с помощью полос прокрутки. Перед на- чалом анимации элемент устанавливается у правой границы экрана. Таким образом, независимо от места нахождения пользователя в документе, ани- мация элемента всегда начинается на странице без большой задержки и пользователь никогда не увидит элемент до начала анимации. <HTML> <HEAD> <TITLE> Плавающий текст </Т1Т1£> <STYLE TYPE="text/css"> Hl {text-align:center} #tip (position:relative; left:-lOOOpx) </STYLE>
Глава 12. Динамическое позиционирование 369 <SCRIPT LANGUAGE="JavaScript"> function slidein() { var el = document.all.tip; // Проверка, находится ли элемент за пределами экрана, if (-1000 == el.style.pixelLeft) { el.style.fontstyle = "italic”; // Размещение элемента за пределами правой границы экрана, el.style.pixelLeft = document.body.offsetWidth + document.body.scrollLeft; ) if (20 <= el.style.pixelLeft) ( el.style.pixelLeft -= 20; setTimeout("slidein()50); ) else { el.style.pixelLeft = 0; el.style.fontstyle = ) ) </SCRIPT> </HEAD> <BODY ONLOAD="slideIn(); "> <H1 ID="tip”>Tip of the Week</Hl> <P>Animating text from off screen </BODY> </HTML> Презентационные эффекты Расширив возможности предыдущего примера, легко можно создать презен- тации с движущимся текстом. Следующий пример демонстрирует добавление элементов презентаций повторяющихся автоматически, или когда пользова- тель щелкает кнопкой мыши. Последовательность эффектов определяется возможностями динамического HTML для представления нераспознаваемых элементов. Элемент sequence определяет набор элементов, которые должны быть анимированы и устанавливает автоматическую анимацию или запуск в ответ на нажатия кнопки мыши. Приведенный ниже документ демонстрирует две серии — первая выполня- ется с использованием таймера, а вторая запускается при нажатии пользова- телем кнопки мыши: <HTML> <HEAD> ' <SEQUENCE order="Textl, Text2, Text3, Text4, Text5" speed="20" type="auto" increments=15>
370 Часть III. Стиль документа и анимация <SEQUENCE order="Text6, Text7" speed="20" type="click" increments=15> <TITLE> Презентационные эффекты </TITLE> <SCRIPT LANGUAGE="JavaScript"? var slideshow = new Object!); function initSequence(s) { var sTemp = s.sequences[s.currentsequence]; if (null != sTemp) ( // Получение списка идентификаторов элементов серии. s.sequencer = new Array(); s.sequencer = sTemp.getAttribute("order").split(", "); // Запуск серии. for (var intLoop = 0; intLoop < s.sequencer.length; intLoop++) if (null != document.all[s.sequencer[intLoop]]) ( var el = document.all[s.sequencer[intLoop]]; el.initTop = el.style.posTop; el.initLeft = el.style.posLeft; ) s.speed = (null == sTemp.getAttribute("speed”)) ? 20: sTemp.getAttribute("speed"); s.type = ("auto" == sTemp.getAttribute("type")); s.increments = (null == sTemp.getAttribute("increments")) ? 15: sTemp.getAttribute("increments") ; s.inc = 0; s.position = -1; ) else { s.position = null; if (document.onclick == doFly) document.onclick = new Function(); function nextSequence(s) ( // Запуск серии, если она доступна. if (null != s.position) ( // s.position представляет элемент в серии. // Выполнение до тех пор, пока имеются элементы; Затем // поиск следующей серии. s.position++ if (s.position < s.sequencer.length) ( s.inc = 0;
Гпава 12. Динамическое позиционирование 371 if (s.type) // Запуск таймера window.setTimeout("doFly() ;", s.speed} else // Запуск при возникновении события нажатия document.onclick = doFly; } else ( s.currentSequence++; initSequence(s); nextSequence(s); ) } else ( s.position = null; if (document.onclick == doFly) document.onclick = null; } ) function slide() ( // Запуск распорядителя серии - получение всех тегов <SEQUENCE>. slideShow.sequences = document.all.tags("SEQUENCE"); slideShow.sequencer = new ArrayO; if (0 < slideShow.sequences.length) ( slideShow.currentsequence = 0; initSequence(slideShow); // Инициализация. nextSequence(slideShow); // Запуск первой серии. ) } function doFly() ( var dt, dl; var el = document.all[slideShow.sequencer[slideShow.position]]; document.onclick ” null; // Остановка событий нажатия до // завершения. // Изменение положения элемента. slideShow.inc++; dt = el.initTop / slideShow.increments; dl = el.initLeft / slideShow.increments; el.style.posTop = el.style.posTop — dt; el.style.posLeft = el.style.posLeft - dl; if (slideShow.inc < slideShow.increments) window.setTimeout("doFly(); ", slideShow.speed) else ( el.style.top =0;
372 Часть III. Стиль документа и анимация el.style.left = 0; nextSequence(slideshow); 1 1 </SCRIPT> <STYLE TYPE="text/css"> BODY (color:white J DIV (position:relative; width:100'л; font-size:16pt; height:40px) Hl (text-align:center; font-size:18pt) </STYLE> </HEAD> <BODY BACKGROUND="img001.gif" ONLOAD="slide();“> <Hl>Inside Dynamic HTML</H1> <DIV ID="Textl" STYLE="top:Opx; left:-350px"> Overview of HTML and CSS</DIV> <DIV ID="Text2" STYLE="top:Opx; left:-350px"> Fundamentals of HTML Scripting</DIV> <DIV ID="Text3" STYLE="top:Opx; left:-350px"> Dynamic HTML Event Model</DIV> <DIV ID="Text4" STYLE="top:Opx; left:-350px"> Dynamic Styles</DIV> <DIV ID=”Text5" STYLE="top:0px; left:-350px; color:yellow"> Click to Continue</DIV> <DIV ID="Text6" STYLE="top:Opx; left:-350px"> Dynamic Contents</DIV> <DIV ID="Text7" STYLE="top:Opx; left:-350px"> Dynamic Presentations!</DIV> </BODY> </HTML> Атрибуты тега <sequence>, который должен быть определен в заголовке документа, перечислены в табл. 12.2. Единственным необходимым атрибутом является атрибут order. Остальные атрибуты принимают значения по умолчанию, если их не определить явно. Таблица 12.2. Атрибуты тега <SEQUENCf:> Имя атрибута Описание order Определяет идентификаторы ((D) элементов, которые должны быть помещены в серию эффектов. Каждый элемент должен быть явно отделен, используя запятую и пробел speed Определяет скорость анимации элементов. Это значение исполь- зуется для определения задержки между элементами, которые воспроизводятся автоматически
Глава 12. Динамическое позиционирование 373 Таблица 12.2 (окончание) Имя атрибута Описание type Определяет запуск последовательности автоматически посредст- вом таймера (по умолчанию, auto) или вручную в ответ на нажа- тие КНОПКИ МЫШИ (click) increments Определяет число промежуточных положений изображения до перехода в финальное положение. Большее число положений при более высокой скорости позволяет создать более плавную анимацию Контекст воспроизведения За невероятную гибкость позиционирования CSS иногда приходится рас- плачиваться увеличением сложности страницы. Приведенные выше приме- ры демонстрируют использование позиционирования CSS для элементов, которые размещаются независимо. Одним из ключевых преимуществ HTML является возможность автоматического изменения схемы размещения со- держания в зависимости от размера содержания и размера окна. Если разра- ботчик Web-страницы предполагает размещать элементы в соответствии с размером окна и содержания, то он должен написать собственный сценарий размещения вместо использования HTML. В общем разработчику проще создавать и поддерживать документы, в которых применяются динамиче- ские стили, используя преимущества природы автоматического потока HTML, чем создавать собственный сценарий размещения. Динамический HTML обеспечивает информацию, которая, несмотря на всю свою сложность, необходима для создания мощной индивидуальной схемы размещения. Для каждого элемента эта информация включает информацию смещения и подлинности элемента, на основе которой рассчитывается сме- щение. Для написания собственных сценариев размещения, необходимо понимать отношения между данными смещениями. Информация о размере и положении каждого элемента в теле документа рассчитывается браузером при каждом обновлении документа, называется информацией воспроизведения и является поэтому менее долговечной, чем информация анализа, которая включает в себя атрибуты, стили и содержа- ние, определяемое атрибутами в исходном документе. Важно понимать раз- личие между значениями, определяемыми документом, и значениями вос- произведения, рассчитанными браузером. Например, значение свойства width может быть для элемента равно 20%, а значение его свойства height может быть не определено. Значение 20%, а также его эквивалент в пикселах, представлены свойством style. Однако
374 Часть III. Стиль документа и анимация значение height не представлено свойством style, поскольку оно не определено. Когда браузер воспроизводит элемент, то его высота рассчиты- вается и представляется в виде отдельного свойства. Кроме того, браузер рассчитывает и представляет верхнее и левое положения элемента. Данные значения не всегда совпадают со значениями top и left, определенными с помощью позиционирования CSS. Каждый элемент позиционируется относительно другого элемента, назы- ваемого его относительным предком (offset parent). Относительный предок элемента устанавливает контекст воспроизведения (rendering context), в котором отображается элемент. Элемент Body является самым высшим отно- сительным предком. Для многих элементов относительным предком являет- ся элемент Body, и браузер рассчитывает положение каждого элемента отно- сительно верхнего левого угла документа. Но если элемент находится внутри абсолютно позиционированного элемента, например, div, то его положение рассчитывается относительно элемента div, который является относитель- ным предком. Относительный предок обеспечивает контекст, в котором воспроизводится элемент. В частности, он определяет точку отсчета для смещений элемента. Каждый элемент описывается уникальной информацией воспроизведения. Свойство offsetparent элемента содержит ссылку на элемент, определяя его контекст воспроизведения, а его свойства offsetTop и offsetLeft содержат его координаты по отношению к началу координат, определенному его свойством offsetparent. Кроме того, прямоугольные элементы обычно опи- сываются свойствами offsetwidth и offsetHeight, которые определяют размер элемента. Только некоторые элементы, принадлежащие определенным стилям, могут определять новые контексты воспроизведения и становиться относительны- ми предками для других элементов. Перечисленные ниже элементы опреде- ляют контексты воспроизведения: □ Элемент Body □ Элементы со значением свойства css position, равным absolute □ Элементы со значениями свойства css position, равным relative (определяет новые контексты воспроизведения только для содержащихся в них абсолютно позиционированных элементов) □ Элементы со значениями CSS float, равными left или right □ Элементы, значения которых явно установлены равными width и height □ Элементы Table, Caption, tr (строка таблицы), td и тн (ячейка таблицы) □ Элементы Fieldset И Legend □ Элементы Marquee □ Элементы Мар
Глава 12. Динамическое позиционирование 375 Каждый элемент имеет одного относительного предка и может определять контекст воспроизведения для любого числа дочерних элементов. В этом отношении относительный предок элемента сходен с его родительским эле- ментом в дереве анализа. Но относительный предок не обязательно должен совпадать с предком элемента в дереве анализа. Свойства offsetparent и parentElement часто указывают на различные элементы. Диаграмма, на ко- торой показаны относительные предки всех элементов в документе, называ- ется деревом воспроизведения (rendering tree) документа. На рис. 12.7 показано дерево анализа и дерево воспроизведения для приве- денного ниже документа. Дерево анализа Дерево воспроизведения Рис. 12.7. Дерево анализа и дерево воспроизведения документа
376 Часть III. Стиль документа и анимация <HTML> . . <HEAD> <TITLE> Анализ дерева относительно дерева воспроизведения </TITLE> </HEAD> <BODY> <P>The parsing tree represents the <EM>containership hierarchy</EM> defined by the contents of the HTML document.</P> <DIV ID=D1 STYLE=”position:absolute; top:60; left:20"> <P>The rendering tree represents the relationship between elements as they are rendered by the browser.</P> <DIV ID=D2 STYLE="height:80; width:100%; overflow:scroll”> <P>This code creates a scrolling element. However, it does not define a new <EM>coordinate system</EM>. The following element is positioned based on the coordinate system of the absolutely positioned DIV.</P> <IMG STYLE="position:absolute; top:60; left:40" SRC="imgl.gif"> </DIV> </DIV> </BODY> </HTML> В данном примере элементы Paragraph, ем и первый элемент div являются дочерними элементами элемента Body. Элемент ем становится дочерним элементом воспроизведения тела документа, поскольку его родительский элемент Paragraph не является ограниченным элементом в соответствии с приведенным выше списком. Первый элемент div, с другой стороны, опре- деляет новый контекст воспроизведения, поскольку он позиционирован аб- солютно. Поэтому все элементы внутри элемента div являются дочерними элементами данного контейнера воспроизведения, если только внутри эле- мента div другой элемент не создает новый контекст воспроизведения. Второй элемент div, D2, также создает новый контекст воспроизведения, поскольку он является ограниченным контейнером. Здесь нужно учесть не- которую хитрость. Если элемент позиционирован абсолютно, то он выделя- ется из потока документа и позиционируется относительно ближайшей ко- ординатной системы. Ограничивающий элемент не обязательно определяет новую систему координат. Прокручивание элемента div, D2. не создаст но- вую систему координат, поскольку не установлено абсолютное или относи- тельное позиционирование. Только элементы со значениями position, рав- ными absolute или relative, создают новые системы координат. Поэтому изображение внутри элемента D2, которое позиционировано абсолютно, в действительности позиционировано относительно первого элемента div, di. Данное отношение также поддерживается в отношениях воспроизведения. Элемент di является относительным предком для элемента D2.
Глава 12. Динамическое позиционирование 377 Демонстрация контекста воспроизведения Отношения между элементом и его контекстом воспроизведения становятся более понятными при рассмотрении примера HTML-документа. Приведен- ный ниже документ, который находится на прилагаемом компакт-диске, выводит информацию о смещениях любого элемента на странице. Документ также содержит примеры создания контекста воспроизведения. Щелчок по любому элементу в документе отображает список смещений для каждого контекста воспроизведения, внутри которого находится элемент. <HTML> <HEAD> <TITLE> Демонстрация смещения </TITLE> <STYLE TYPE=”text/css"> BODY, TD, DIV, CAPTION, FIELDSET, LEGEND (cursor:default) </STYLE> <SCRIPT LANGUAGE*3"JavaScript"> function doClick() ( // Построение строки, содержащей все значения смещений, // начиная с нажатого элемента. var el = event.srcElement; var offset = "Offsets\n"; while (el != null) { offset += "\n" + el.tagName + (” + el.offsetTop + ", " + el.offsetLeft + ")"; el = el.offsetParent; ) alert(offset); ) document.onclick = doClick; </SCRIPT> </HEAD> • <BODY> <Hl>Offset Demonstration</Hl> <P>Click on an element to see its rendering context and offset relationship. This page helps demonstrate how an element becomes constrained and creates a new rendering context for the elements it contains. <P>This is a standard paragraph containing <EM>emphasized text</EM>. , . • <TABLE BORDER> <CAPTION>Table <EM>Demo</EMx/CAPTION> , <TRxTD>Table Cell 1</TD> <TD>Table Cell <STRONG>2</STRONGx/TDx/TR> <TRxTD>Table Cell 3</TDXTD>Table Cell 4</TD></TR>
378 Часть III. Стиль документа и анимация </TABLE> <FIELDSET STYLE="width:200pt"> • . <LEGEND>Fieldset <EM>Demo</EMx/LEGEND> <P>This is a fieldset. <BUTTON><P>HTML <STRONG>Button</STRONGx/BUTTON> ' ' t, . </FIELDSET> <P STYLE="position:relative; top:50; left:160pt">This is a <EM>relatively</EM> positioned paragraph.</P> <DIV STYLE="overflow:auto; height:50pt; width:150pt border:lpt gray solid"> <P>This DIV element has a constrained width and height and may display scrollbars if the contents <EM>do not</EM> fit. , ... . </DIV> <DIV STYLE="position:absolute; top:300pt; left:150pt; width:lOOpt; border:lpt gray solid"> <DIV STYLE="position:absolute; top:0pt; left:120pt; width:lOOpt; border:lpt gray solid"> <P>This is an absolutely positioned DIV element within another absolutely positioned DIV element. </DIV> <P>This is an absolutely positioned DIV element.</P> </DIV> </BODY> </HTML> Свойства смещения относительно позиционированных элементов Свойства стиля top и left относительно позиционированных элементов представляют его смещения относительно нормального положения в потоке, а его свойства offsetTop и offsetLeft представляют его положение по от- Q flcldlivt: 1>оы1шЛ1ОД and llthul PiufMutws - I hl - KPI ltd ношению к его относительному предку. На рис. 12.8 показаны отношения между этими свой- ствами стиля и воспроизводи- мыми свойствами положения. Рисч 12.8. Свойства стиля top и left и свойства offsetTop и offsetLeft относительно позиционированного элемента
Глава 12. Динамическое позиционирование 379 Свойства смещения являются только свойствами воспроизведения, которые представляют рассчитанные положения элемента в документе. Определение отображения элемента Приведенная ниже функция определяет, отображается ли верхний левый угол элемента на экране. Данная функция возвращает false, если верхний левый угол элемента невидим на экране, даже если элемент частично ото- бражается на экране. Функция может быть применена к любому элементу на странице. function onscreen(е) ( // Проверка, является ли указанный элемент видимым. var гр = e.offsetParent; if (гр == null) return false; ' var pleft = e.offsetLeft; var ptop = e.offsetTop; while (true) { if (!((pleft >= rp.scrollLeft) && (pleft <= rp.scrollLeft + rp.clientwidth) && (ptop >= rp.scrollTop) &S (ptop <= rp.scrollTop + rp.clientHeight))) return false; pleft += rp.offsetLeft — rp.scrollLeft; ptop += rp.offsetTop — rp.scrollTop; rp = rp.offsetparent; if (rp == null) return true; ) } Данный код может быть легко расширен для проверки отображения на эк- ране внутреннего элемента управления или ограничивающего элемента пу- тем определения ширины и высоты элемента. Но метод не будет работать для непрямоугольных элементов, поскольку они не содержат свойства offsetwidth И offsetHeight. Прокручивание элемента Элемент в теле документа может быть открыт для просмотра с помощью метода scroiiintoview. Метод scroliintoview поддерживает одиночный не- обязательный параметр, который определяет чюявление элемента в первой или последней строке в окне. Пропуск данного параметра или присвоение ему значения true прокручивает элемент до первой строки. Значение false
380 Часть III. Стиль документа и анимация прокручивает элемент до последней строки. Например, приведенный ниже код прокручивает первый элемент Н1: // Прокручивание элемента к первой строке. document.all.tags("Hl").item(O).scrollIntoView() // Прокручивание элемента к последней строке. document.all.tags("Hl").item(O).scrollIntoView(false) Идентификация элемента в выбранном положении Метод elementFromPoint объекта document используется для идентификации элемента в определенном положении в координатах ху на экране. Данный метод принимает положение в xy-пикселах относительно области клиент- ского окна и возвращает объект элемента в данном положении. Метод elementFromPoint используется для определения элемента, на котором нахо- дится мышь во время работы обработчика событий. Например, приведен- ный ниже код помещает имя тега элемента, над которым находится указа- тель мыши, в текстовое окно: <HTML> . - . <HEAD> <TITLE> Где находится указатель мыши? </TITLE> <SCRIPT FOR="document" EVENT="onmousemove()" LANGUAGE="JavaScript"> document.all.txtCurrent.value = document.elementFromPoint(event.x, event.у).tagName; </SCRIPT> </HEAD> <BODY> <Hl>This Is a <EM>Header.</EMx/Hl> <P>Current Element: CINPUT TYPE=TEXT ID="txtCurrent" SIZE=20> </P> </BODY> , </HTML> Элемент Map Элемент мар определяет специальный контекст воспроизведения. Поскольку элемент мар может быть использован несколькими изображениями, то он считается находящимся за пределами контекстов воспроизведения. Поэтому элемент мар возвращает null для свойства offsetparent и о для свойств offsetTop и offsetLeft. Элементы Area внутрЪ элемента мар возвращают значения для их свойств offsetTop и offsetLeft относительно верхнего ле- вого угла элемента, содержащего мар, и возвращают элемент мар в качестве
Глава 12. Динамическое позиционирование 381 относительного предка. Поэтому, чтобы определить положение элемента Area на экране, необходимо учесть смещения определенного изображения. Выравнивание относительно позиционированных элементов Выравнивание элементов по горизонтали или по вертикали может представ- лять собой достаточно сложную операцию, требующую достаточное количе- ство кода. При наличии двух абсолютно позиционированных элементов внутри одной системы координат выравнивание элементов также просто, как указание одинаковых значений свойств top и left. Поскольку относи- тельно позиционированные элементы сдвинуты по отношению к их поло- жению в потоке, то выравнивание относительно позиционированных эле- ментов требует нескольких строк кода. Приведенный ниже документ демонстрирует, как собрать все относительно позиционированные элементы друг над другом и затем переместить их об- ратно в нормальные положения в документе. Выравнивание элементов вы- полняется функцией alignElements, принимающей любые относительно по- зиционированные элементы и помещающей их над элементом с идентифи- катором id, равным src. В противном случае вместо такого элемента может быть использована фиксированная точка на экране. <HTML> <HEAD> <TITLE> Анимация из одной точки </TITLE> <STYLE TYPE="text/css"> .fly {position:relative; color:navy; visibility:hidden) </STYLE> <SCRIPT LANGUAGE="JavaScript"> function alignElements(el) ( /* Помещение передаваемого в функцию относительно позиционированного элемента, который находится в той же системе координат над элементом, идентификатор которого равен src. */ el.s tyle.pixelTop = document.all.src.offsetTop — el.offsetTop; el.style.pixelLeft = document.all.src.offsetLeft — el.offsetLeft; el.style.visibility = "visible"; function moveln(el) { // Если элемент не находится в своем положении в потоке, то // переместить его ближе к этому месту, var moved = false;
2S2 Часть III. Стиль документа и анимация if (el.style.pixelTop < 0) { el.style.pixelTop += 8; ’ if (el.style.pixelTop > 0) el.style.pixelTop = 0; moved = true; ) else { if (el.style.pixelTop > 0) { el.style.pixelTop -= 8; if (el.style.pixelTop < 0) el.style.pixelTop = 0; moved = true; ) } if (el.style.pixelLeft < 0) { el.style.pixelLeft += 8; if (el.style.pixelLeft > 0) el.style.pixelLeft = 0; moved = true; } else ( if (el.style.pixelTop > 0) { el.style.pixelLeft -= 8; if {el.style.pixelLeft < 0} el.style.pixelLeft = 0,- moved - true; .J . . • /* Переменная перемещения отражает, был ли перемещен элемент. Если элемент уже перемещен в соответствующее положение в потоке, то данная функция возвращает false. */ return moved; ) function flylnTogether() { var more = false; // Перемещение всех элементов класса fly. for (var intLoop = 0; intLoop < document.all.length; intLoop++) { if ("fly" == document.all[intLoop].className) more = movein(document.all[intLoop]) II more; I/ Продолжает выполнение до тех пор, пока все элементы не // будут соответствующим образом размещены в потоке, if (more) setTimeout(”flylnTogether()", 10); }
Глава 12. Динамическое позиционирование 383 function setup() { . // Выравнивание всех элементов, которые должны быть анимированы, for (var intLoop = 0; intLoop < document.a11.length; intLoop++) { if ("fly" == document.all[intLoop].className) alignElements(document.all[intLoop]); } flylnTogether(); ) window.onload = setup; </SCRIPT> </HEAD> <BODY> <H1 ID=src>Animate from a Single Point</Hl> <UL> <LI CLASS=''fly"XP>Create animated documents.</P> <LI CLASS="fly"XP>All elements start together at a single point.</P> <LI CLASS="fly"XP>This example works using relative positioning.</P> <LI CLASS="fly"XP>First align the elements, and then fly them into place.</P> <LI CLASS="fly"XP>Once the elements are in place, this is a standard HTML document!</P> CLI CLASS=”fly"XP>Simply supplying a special class name animates an element.</P> </UL> <P STYLE-"text-align:center">Not all text must be animated! </BODY> </HTML>

Содержание документа и связывание данных Глава 13. Динамическое содержание Глава 14. Пользовательские операции выделения и редактирования Глава 15. Связывание данных с помощью HTML

Глава 13 Динамическое содержание Термин динамическое содержание (dynamic contents) подразумевает возмож- ность доступа и изменения части содержания документа без необходимости загрузки или создания новой страницы. Хорошим примером динамического содержания являются электронные часы, которые автоматически обновля- ются в HTML-документе каждую секунду без необходимости генерации но- вого документа. Динамический HTML обеспечивает прямой доступ ко всем элементам до- кумента вплоть до отдельных символов. Такая система доступа позволяет быстро и оперативно обновлять документ. При обновлении документа ок- ружающее его содержание может быть переформатировано в зависимости от размера и положения нового содержания. Переформатирование документа также часто происходит при использовании динамических стилей, когда размер или отображение документа изменяются. Динамическое содержание расширяет возможности изменения текста и HTML на странице в данной модели. Наиболее эффективным способом изучения динамического манипулирова- ния документом является анализ кода, поэтому в данной главе рассматри- ваются примеры кода, относящиеся к перечисленным ниже темам: □ Манипулирование содержанием. В данном разделе кратко вводятся три метода манипулирования содержанием, поддерживаемые динамическим HTML. □ Свойства динамического содержания. Содержание элемента представлено посредством четырех свойств и двух методов. Данные свойства обеспечи- вают наиболее быстрый и прямой способ доступа и изменения содержа- ния документа. В разделе обсуждается использование свойств для изме- нения содержания элемента, а также взаимодействие данных свойств с документом. □ Динамическое содержание и метод document.write. Метод document.write позволяет вставлять содержание на страницу во время ее загрузки.
388 Часть IV. Содержание документа и связывание данных Динамическое содержание позволяет манипулировать содержанием после загрузки страницы. В данном разделе представлены методы совместного использования данных возможностей с целью создания интерактивных документов. Манипулирование содержанием Динамический HTML представляет перечисленные ниже три подхода для манипулирования содержанием документа. Первый подход используется для генерации содержания во время загрузки страницы, а два других применя- ются для манипулирования документом после загрузки страницы: □ Запись содержания в поток во время загрузки страницы. □ Манипулирование содержанием при помощи свойств и методов, пред- ставленных для всех элементов в теле документа. □ Программирование объекта TextRange, который представляет объектную модель для текста документа. Первый подход использует методы write и writein объекта document, кото- рые могут вставлять содержание в текущий документ при его загрузке и могут конструировать документы, но они не могут изменять содержание, которое уже было проанализировано. В главе 6 обсуждались методы write документа. Методы write и writein поддер- живаются в браузерах Netscape Navigator версии 2.0 и более поздних и Microsoft Internet Explorer 3.0. Последние два метода составляют динамическое содержание и впервые поя- вились в Internet Explorer 4.0. Все элементы в теле документа обеспечивают прямой доступ к содержанию любого элемента при помощи четырех свойств и двух методов, которые предоставляют самый простой метод доступа и изме- нения содержания документа и являются предметом обсуждения этой главы. Объект TextRange представляет индивидуальную текстовую объектную мо- дель, которая обеспечивает произвольный доступ к основному содержанию, расширяя возможности управления документом за счет снижения предска- зуемости. Данный метод позволяет манипулировать содержанием гак же, как и с помощью текстового редактора. Эта модель не является такой же точной, как переход по дереву сверху вниз и имеет ряд ограничений. В главе 14рассматриваются сильные и слабые стороны объектной модели TextRange. Свойства динамического содержания Элемент Body и все элементы, находящиеся внутри него, представляют че- тыре свойства для доступа и изменения содержания HTML: innerHTML, innerText, outerHTML и outerText. Свойство innerHTML элемента представляет
Гпава 13. Динамическое содержание 389 его содержание, включая разметку HTML для всех дочерних элементов. Свойство innerText представляет содержащийся текст без тегов HTML. Присвоение нового значения одному из внутренних свойств элемента заме- няет содержание документа. Свойства outerHTML и outerText сходны со свойствами innerHTML и innerText, но они обращаются ко всему элементу, а не к его содержанию. Присвоение значения одному из внешних свойств элемента заменяет весь элемент. В приведенном ниже примере нажатие кнопки заменяет кнопку на полужирный текст Blown away!: <HTML> <HEAD> <TITLE> Исчезающая кнопка </TITLE> </HEAD> <BODY> CINPUT TYPE=BUTTON VALUE="Blow me away!” • ONCLICK=”this.outerHTML = ’<B>Blown Away!</B>’"> </BODY> </HTML> !j ' ' : Ограничением данных свойств является то, что они могут обращаться к элементу или его содержанию только как к целому. Например, для того что- бы использовать данные свойства с целью изменения третьего символа или слова внутри элемента, вам потребовалось бы изменить строку и снова ее вставить. Объект TextRange предоставляет альтернативный метод, который позволяет напрямую манипулировать любой частью документа. Свойства динамического содержания используют достаточно строгие прави- ла для определения действительности HTML. Эти правила более конкретны, чем правила, используемые для исходного анализа страницы, но они не на- столько строги как определение типа документа (DTD) HTML. Если вы на- значаете недействительный HTML одному из данных свойств, то мо- жет возникнуть ошибка и новое содержание не будет вставлено. Хотя свойства принимают не- которые недействительные теги HTML, вам следует всегда ука- зывать разрешенный синтаксис HTML для получения предсказу- емых результатов. Рис. 13.1. Все точки доступа и изменения HTML и текста
390 Часть IV. Содержание документа и связывание данных Кроме данных свойств каждый элемент в теле документа также представляет два метода для вставки содержания до или после открывающего или закры- вающего тега: insertAdjacentHTML И insertAdjacentText. Эти два метода по- лезны для быстрой вставки новых параграфов или элементов списков в до- кумент. На рис. 13.1 показаны все способы манипулирования содержанием элемента. «• * . • HTML и свойства текста Главное различие между свойствами HTML innerHTML и outerHTML с одной стороны и текстовыми свойствами innerText и outerText с другой заключа- ется в том, что свойства HTML представляют разметку целиком, тогда как свойства текста представляют содержание без разметки. Рассмотрим сле- дующий фрагмент HTML: <Hl>Welcome to <EM>Scott's</EM> Home Page</Hl> Для элемента hi в данном фрагменте в табл. 13.1 перечислены значения ка- ждого из четырех свойств. Таблица 13.1. Свойства HTML и свойства текста Свойство Значание innerText Welcome to Scott's Home Page innerHTML Welcome to <EM>Scott's</EM> Home Page outerText Welcome to Scott's Home Page outerHTML <H1>Welcome to <EM>Scott's</EM> Home Page</H1> Свойства innerText и outerText всегда .возвращают одинаковое значение, но ведут себя по-разному при назначении им новых значений. Установка зна- чения для свойства innerText заменяет только содержание элемента hi но- вым содержанием. Установка значения для свойства outerText заменяет элемент hi и его содержание новым текстом. Например, установка значения "Thank you for visiting' (Спасибо, что зашли) для этих свойств будет иметь различный результат: для свойства innerText будет получен результирующий <hi Thank you for visiting</Hi>, а если значение присвоено свойству outerText, ТО В коде HTML будут отсутствовать теги: Thank you for visiting. Разметка в значениях свойств innerHTML и outerHTML необязательно совпада- ет с разметкой в исходном коде. Напротив, удаляются избыточные пробелы и порядок атрибутов может быть изменен. Присваивая значения свойствам, связанным с HTML, убедитесь в использовании соответствующих escape- последовательностей любых компонентов (entity). Угловые скобки < и > ин-
Глава 13. Динамическое содержание 391 терпретируются как разделители тегов. Если угловые скобки должны быть включены в содержание и не должны анализироваться как HTML, то они должны быть определены как компоненты: &it; и iqt;. Когда вы присваи- ваете значения текстовым свойствам, то данные скобки автоматически пре- образуются в эквиваленты escape-последовательностей. Неразрывные пробелы Неразрывные пробелы (nonbreaking spaces) (пробелы, в которых запрещены символы перехода строки) и обычные пробелы считаются разными симво- лами в объектной модели, где они представлены значениями ASCII 160 и 32, соответственно. Сравнение двух символов дает значение false, как по- казано в приведенном ниже примере: <SPAN ID="sl">&nbsp;</SPAN> document.all.si.innerText == " ” // false; не пробел Для проверки наличия в содержании элемента неразрывного пробела про- верьте непосредственно значение ASCII или сравните свойство HTML с са- мим компонентом, как показано ниже: document.all.si.innerHTML == "Snbsp;" // true Любой определенный компонент, который совпадает со значением внут- реннего компонента преобразуется во внутреннее имя. Компонент нераз- рывного пробела может быть определен как &#1бо; вместо идентифицирую- щего его ключевого слова. Динамический HTML распознает данное значе- ние как неразрывный пробел и преобразует его в snbsp;. Применение свойств динамического содержания Самым простым способом изучения различий между свойствами динамиче- ского содержания элемента является анализ примеров. В приведенных ниже разделах представлены два примера: первый пример представляет собой анализ электронных часов из главы 4, а второй представляет игру в крести- ки-нолики, которая демонстрирует динамическое извлечение содержания и назначение содержания документу. Электронные часы В примере электронных часов из главы 4 для обновления значения времени было использовано свойство innerText. Элемент span с идентификатором clock содержит текст с текущим временем. Каждую секунду сценарий вы- зывает функцию buildTime для создания строки со значением текущего времени и затем выводит строку в элементе <>рап с идентификатором clock, используя следующую инструкцию: document.all.clock.innerText = buildTime ();
392 Часть IV. Содержание документа и связывание данных Игра в крестики-нолики Данный пример является интерактивной игрой в крестики-нолики с ис- пользованием динамического содержания. Таблица разделена на игровые ячейки. Когда пользователь выполняет щелчок в ячейке, то ее содержание заменяется на х или о, для чего применяется свойство innerText. Размер игровой доски может динамически изменяться путем вставки новой табли- цы вместо имеющейся при помощи свойства outerHTML. <HTML> <HEAD> <TITLE> Крестики-нолики </TITLE> <STYLE TYPE=”text/css"> TD {font-weight:bold) #board TD (width:50px; height:50px; text-align:center; font-size:18pt; cursor:hand) .X (color:blue) .О (color:red) .draw (color:green) </STYLE> <SCRIPT LANGUAGE*»"JavaScript"> function TicTacO ( // Объект для отслеживания игры this.lastMove = true; this.inProcess = true; this.scores = new Object(); this.scores.xScore = 0; this.scores.oScore = 0; this.Scores.draws = 0; this.size = 3; this.drawBoard = initBoard; ) function buildTableQ ( // Построение HTML-таблицы, которая должна быть вставлена в документ, var tb = "<TABLE BORDER ID=board ONCLICK='doBoardClick() ; '>"; for (var intRow = 0; intRow < game.size; intRow++) ( tb += "<TR>"; for (var intCell = 0; intCell < game.size; intCell++) tb += ”<TD>Snbsp;</TD>"; tb += "</TR>"; ) tb += ”</TABLE>"; return tb; )
Гпава 13. Динамическое содержание 393 function initBoard() ( document.all.board.outerHTML = buildTable(); game.inProcess = true; ... game.lastMove = true; ) function checkwinner(xCount, oCount) ( // Обработка результатов для выяснения возможности победы. if (game.size == xCount) { alert("X Wins!”); game.scores.xScore++; return false; ) if (game.size == oCount) ( alert("0 Wins!”); game.scores.oScore++; return false; } return true; ) function checkGame() { // Проверка всех направлений для выяснения вероятности выигрыша, var xCount = 0, oCount = 0, total = 0; var el = document.all.board; // Проверка строк. for (var intRows = 0; intRows < el.rows.length; intRows++) ( xCount = 0, oCount = 0; for (var intCells = 0; intCells < el.rows[intRows].cells.length; intCells++) ( var strCell = el.rows[intRows].cells[intCells]; if ("X" = strCell.innerText) xCount++; if ("O" == strCell.innerText) oCount++; ) game.inProcess - checkwinner(xCount, oCount); if (!game.inProcess) return; total += xCount + oCount; } // Проверка столбцов. for (var intCells = 0; intCells < el.rows.length; intCells++) ( xCount = 0, oCount = 0;
394 Часть IV. Содержание документа и связывание данных for (var intRows = 0; intRows < el.rows[intCells].cells.length; intRows++) ( var strCell = el.rows[intRows].cells[intCells); if (x" = strCell. innerText) xCount++; if ("O" == strCell.innerText) oCount++; ) game.inProcess = checkwinner(xCount, oCount); if ([game.inProcess) return; ) // Проверка диагонали (от верхнего левого до нижнего правого угла). xCount = 0, oCount = 0; for (var intRows = 0; intRows < el.rows.length; intRows++) ( var strCell = el.rows[intRows].cells[intRows]; if ("X" == strCell.innerText) xCount++; if ("0" == strCell.innerText) oCount++; } game.inProcess = checkwinner(xCount, oCount); if ([game.inProcess) return; // Проверка диагонали (нижний левый угол — верхний правый угол). xCount = 0, oCount = 0; for (var intRows = 0; intRows < el.rows.length; intRows++) ( var strCell = el.rows[game.size — intRows — 1).cells[intRows]; if ("X" = strCell.innerText) xCount++; if ("O” == strCell.innerText) oCount++; ) game.inProcess = checkwinner(xCount, oCount); if ([game.inProcess) return; if (total = game.size * game.size) ( alert("draw"); game.inProcess = false; game.scores.draws++; return
Гпава 13. Динамическое содержание 395 function updateScore() ( // Вывод нового счета, for (scores in game.scores) document.all(scores).innerText = game.scores[scores]; } function doBoardClick() ( if (game.inProcess) ( if ("TD" == event.srcElement.tagName) ( var strCell = event.srcElement; // Проверка доступности ячейки, if ("&nbsp;” = strCell.innerHTML) ( strCell.innerText = (game.lastMove ? "X”: "0"); event.srcElement.className = game.lastMove ? "X": "0"; game.lastMove = (game.lastMove; ) . . ) checkGame(); if (!game.inProcess) updateScore(); } } // Управление переменными игры var game = new TicTac; </SCRIPT> CSCRIPT FOR="size" EVENT="onclick() LANGUAGE=”JavaScript"> // Разделяемый обработчик событий для кнопок-переключателей размера доски game.size = parseint(this.value); game.drawBoard(); c/SCRIPT> C/HEAD> CBODY> cHl>Tic-Tac-Toec/Hl> cPxINPUT TYPE=BUTTON VALUE=”New Game" ONCLICK="game.drawBoard();"> CPxINPUT NAME=size TYPE=RADIO VALUE="3" ID="x3" checked> CLABEL FOR=”x3">3 x 3c/LABEL>CBR> CINPUT NAME=size TYPE=RADIO VALUE="4" ID="x4"> CLABEL FOR="x4">4 x 4c/LABELxBR> CINPUT NAME=size TYPE=RADIO VALUE="5" ID="x5"> CLABEL FOR="x5">5 x 5c/LABEL> CP> CSCRIPT LANGUAGE="JavaScript"> document.write(buildTable());
396 Часть IV. Содержание документа и связывание данных </SCRIPT> <TABLE> < TR class=x><TD>X Wins:</TD><TD ID=xScore>0</TDx/TR> < TR class=oxTD>O Wins:</TDXTD ID=oScore>0</TDx/TR> < TR class=drawXTD>Draws:</TDXTD ID=draws>O</TDx/TR> </TABLE> </BODY> </HTML> Q Iic-fac-Toe • Microsoft Inte... Tic-Tac-Toe 3x3 C 4x4 О Wins: 0 Draws: 0 Э My Carols:;” £<# So Ejratto ‘ На рис. 13.2 показана игра в крестики-нолики в действии. Рис. 13.2. Крестики-нолики Использование методов Adjacent Методы insertAdjacentHTML И insertAdjacentText вставляют HTML и текст до или после откры- вающего или закрывающего тегов. Оба метода принимают два аргумента: первый аргумент оп- ределяет место вставки содержания, а второй определяет реальное содержание. Четыре действительных значения для перво- го аргумента представляют соответственно че- тыре места вставки: beforeBegin, afterBegin, beforeEnd И afterEnd, где СЛОВО Begin представ- ляет открывающий тег, а слово End — закры- вающий. Эти методы полезны для вставки со- держания, которое не оказывает влияния на те- кущее содержание документа. Создание примечаний В данном примере продемонстрировано добавление на страницу всплываю- щих примечаний. Приведенный ниже код размешает все элементы, которые определены как примечания, и вставляет номера примечаний в документ. Автор определяет примечание, добавляя элемент Span с именем класса footnote. Таблица стилей определяет элементы Span как невидимые. Окно сообщения, содержащее текст примечания, отображается при щелчке по номеру примечания. <HTML> <HEAD> <TITLE> Динамические примечания </TITLE> <STYLE TYPE="text/css">
Глава 13. Динамическое содержание 397 SPAN (display:none) SUP.FNID (color:blue; cursor:hand) </STYLE> <SCRIPT LANGUAGE="JavaScript"> function setupFootnotes() { // Получение семейства всех элементов Span. var spans = document.all.tags("SPAN"); for (var i = 0; i < spans.length; i++) { var el = spans[i]; // Если элемент является примечанием, то он обрабатывается, if ("footnote" == el.className) { // Добавление номера примечания в виде цифры индекса, el.insertAdjacentHTML("beforeBegin", "<SUP CLASS=FNID>" + (i + 1) + " </SUP>"); // Связывание номера примечания с элементом Span, document.allfel.sourceindex — 1].linkFN = el; ) ) ' function displayFNO ( // Если пользователь щелкнул по номеру примечания, то на // экран выводится его текст. if ("FNID” == event.srcElement.className) if (null != event.srcElement.linkFN) alert(event.srcElement.linkFN.innerText); ) window.onload = setupFootnotes; document.onclick = displayFN; </SCRIPT> </HEAD> <BODY> <Hl>Dynamic Footnotes <SPAN CLASS="footnote"> Copyright (C) 1997 by Scott Isaacs. </SPAN> </Hl> <P>Dynamic HTML is a "powerful way of creating Web pages" <SPAN CLASS="footnote">Scott Isaacs, "Inside Dynamic HTML." </SPAN> and "Soon Dynamic HTML will be used in most applications." <SPAN CLASS="footnote"> Joe-Cool Developer, "The Future of the Web." </SPAN>
398 Часть IV. Содержание документа и связывание данных <P>This page automatically generates and numbers the footnotes at load time. The footnotes are stored as hidden contents on the page.</P> </BODY> </HTML> Вы можете вывести на экран примечания в виде всплывающих подсказок, а не в окнах сообщений, установив атрибут title каждого номера примеча- ния для текста примечания. Можно также вывести содержание примечания в тексте документа, после щелчка по номеру примечания. Для применения данного метода настройте функцию displayFN для изменения атрибута сти- ля display текста примечания. Создание полей со списком в формате HTML В данном примере используются элементы HTML для моделирования двух полей со списками, элементы которых могут быть скопированы из одного списка в другой. Одиночное индивидуальное поле со списком также может быть использовано для расширения возможностей выбора. В следующем примере с использованием элементов div с прокручиванием создаются два поля со списками. Каждый элемент в нолях со списками является стандартным элементом маркированного списка. Щелчок по элементу вызывает изменение цвета фона. Двойной щелчок по элементу или по одной из кнопок со стрелками вызывает удаление элемента из од- ного списка и помещает его в конец другого списка с помощью метода insertAdjacentHTML. <HTML> <HEAD> <TITLE> Индивидуальные HTML-поля co списками </TITLE> <STYLE TYPE="text/css"> • list (cursor:hand; overflow.auto; height:75pt; width:150pt; border:lpt black solid) .list UL {list-style-type:none; margin-left:2pt; margin-top:Opt; margin-bottom:Opt} •list UL LI (margin-top:Opt; margin-bottom:Opt} .list UL LI.selected (background:navy; color:white) </STYLE> <SCRIPT LANGUAGE="JavaScript"> function checkParent(sre, tag) ( while ("HTML" 1= sre.tagName) ( if (tag = sre.tagName) return sre; sre = sre.parentEiement; )
Глава 13. Динамическое содержание 399 return null; ) function selectitem (list) { var el = checkParent(event.srcElement, "LI"); if ("LI" == el.tagName) { if (null != list.selected) list.selected.className = ; if (list.selected != el) ( el.className = "selected”; list.selected = el; } else list.selected - null; } ) function copy(src, dest) { var elSrc = document.all[src] ; •var elDest = document.all[dest]; if (elSrc.selected != null) ( elSrc.selected.className = elDest.insertAdjacentHTML("beforeEnd”, elSrc.selected.outerHTML); elSrc.selected.outerHTML = elSrc.selected = null; // начальная установка выбора ) ) </SCRIPT> </HEAD> <BODY> <Hl>Custom HTML List Boxes</Hl> <P>The bulleted lists simulate rich HTML selection lists.</P> <TABLE> <TR> . . ' <TD> <DIV CLASS="list"> <UL ID="src" ONCLICK="selectItem(this);" ONDBLCLICK="copy(’src’, ’dest');"> <LI>Scott's <EM>Home</EM> Page</LI> <LI>Parents’ Home Page</LI> cLIXIMG SRC="foo.gif"x/LI> <LI>Inside Dynamic HTML Home Page</LI> <LI>Microsoft Home Page</LI> <LI>Item 6</LI>
400 Часть IV. Содержание документа и связывание данных <LI>Item 7</Ы> • </UL> </DIV> </TDXTD> <PXINPUT TYPE=BUTTON VALUE="->" ONCLICK="copy('src’, ’dest');"> <PXINPUT TYPE=BUTTON VALUE="<-” ONCLICK="copy('dest', 'src’);"> </TDXTD> <DIV class="list”> <UL ID="dest" ONCLICK="selectItem(this) ONDBLCLICK=”copy('dest', 'src1);"> </UL> </DIV> </TD> </TR> </TABLE> </BODY> </HTML> На рис. 13.3 показаны индивидуальные поля со списками. Custom HTML List Bowes - Mrciosoft Internet Exploier Efe kW. fio ТдуыЬ», _______ Custom HTML List Boxes Рис. 13.3. Два поля co списками, созданными на основе существующих HTM L- элементов Доступ к содержанию Доступ к содержанию документа и его изменение возможно только после окончания загрузки документа. Поэтому следует соблюдать осторожность, когда сценарий или обработчик событий пытаются получить доступ и мани- пулировать содержанием документа. Если код мЬжет выполняться до окон- чания загрузки страницы, то он должен сначала проверить значение свойст- ва readyState документа:
Гпава 13. Динамическое содержание 401 if ("complete" == document.readyState) { // Манипулирование содержанием. 1 else { // Отображение предупреждения или выполнение альтернативного действия. ) Обработка ошибок изображений Следующий пример показывает, как организовать очередь изменений доку- мента до окончания полной загрузки страницы. В данном примере все изо- бражения, которые не удалось загрузить, заменяются на сообщения об ошибке и заголовки изображений. Хитрость здесь заключается в том, чтобы гарантировать обращение к содержанию документа только после окончания его загрузки, так как если изображение не удастся загрузить, то оно сгене- рирует событие onerror до окончания полной загрузки страницы. Приведенный ниже код создает семейство всех изображений, которые нс удалось-загрузить до полной загрузки страницы. После загрузки страницы все изображения в очереди незаконченных изображений заменяются на со- ответствующий текст. Все последующие ошибки сразу же обрабатываются. <HTML> <HEAD> <TITLE> Обработка ошибок изображений </TITLE> <STYLE TYPE="text/css"> SPAN, error (background.-yellow; font-weight .-bold} </STYLE> <SCRIPT LANGUAGE=”JavaScript"> var Errors = new ArrayO; Errors[0] = 0; function badlmage(el) { if (document.readyState != "complete"} ( Errors[0]++; Errors(Errors(0]] = el; ' .......... ) else // Документ загружается. Прямой вывод ошибки. el.outerHTML = "<SPAN CLASS=1 error1>Error Loading Image: " + el.title + ”</SPAN>"; ) function reviewErrors(} ( for (var i = 1; i <= Errors(O); i++)
402 Часть IV. Содержание документа и связывание данных Errors[i].outerHTML - • • "<SPAN CLASS='error’>Error Loading Image: " + Errors[i].title + "</SPAN>"; 1 window.onload = reviewErrors; </SCRIPT> </HEAD> <BODY> <PXIMG SRC=”bad.gif" ONERROR="badImage(this);" TITLE="Cool Picture"> <PXA HREF="http: //www. insideDHTML.com"> <IMG SRC="bad.gif" ONERROR="badImage(this);" TITLE="Inside Dynamic HTML Web Site"x/A> </BODY> </HTML> Данный код работает только в том случае, если якорь содержит изображе- ние. Новый текст, который заменяет изображение, воспроизводится внутри якоря и соответственно переходит на страницу при щелчке по элементу. Данный код может быть расширен для вывода сообщения после события onabort. Если замена изображения на текст невозможна, то можно легко изменить атрибут title, добавив сообщение об ошибке. (Атрибут title в Internet Explorer 4.0 отображается как всплывающая подсказка). Данная модифика- ция может быть реализована без создания очереди ошибок, потому что ат- рибуты элементов могут быть изменены до загрузки страницы. Приведен- ный ниже фрагмент кода демонстрирует добавление данного элемента. Эта схема работает без дополнительного кода: <IMG SRC="bad.gif" TITLE="Cool Picture" ONERROR="this.title = 'Error Loading: 1 + this.title",•> Динамическое содержание и метод document.write Модель динамического содержания является мощным инструментом мани- пулирования загруженным изображением, но не исключает необходимости применения метода document.write. Эти два элемента очень хорошо допол- няют друг друга. В приведенных ниже примерах методы динамического со- держания используются для размещения опредеЛиного текста, который за- тем при помощи метода document.write выводится в новом окне. Первая схема создает фрейм баннера (banner — в переводе с английского означает:
Глава 13. Динамическое содержание 403 знамя, лозунг, шапка, заголовок. — Примеч. ред.), когда документ находится внутри набора фреймов, а вторая демонстрирует два метода индексирования страницы. Создание строки заголовка Разработчики Web-страниц давно мечтали о том времени, когда в заголовке над HTML-страницей можно будет отображать текст баннера. В ранних вер- сиях браузеров это достигалось только путем создания набора фреймов, ко- торый загружает два файла одновременно, файл документа и файл баннера. Использование двух файлов для документа повышает сложность страницы, так как файлы должны быть синхронизированы. Приведенный ниже код упрощает ситуацию, включая баннер в содержание документа. Если страни- ца загружается за пределами набора фреймов, то код отображает баннер внутри документа, поэтому достоверность информации в документе не будет нарушена. <HTML> <HEAD> <TITLE> Документ баннера </TITLE> <STYLE TYPE="text/css"> DIV#bannerContents (display:none 1 </STYLE> <SCRIPT LANGUAGE="JavaScript"> function outputBanner(} { if (null != parent.frames[0]) { parent.f rames[0)- document.open(}; parent.frames[0].document.write( document.all.bannercontents.outerHTML); parent.framesf0].document.closed; 1 else // Отсутствует набор фреймов; включается баннер, document.all.bannercontents.style.display = "block"; } window.onload = outputBanner; </SCRIPT> </HEAD> <BODY> <DIV ID=bannerContents> <Hl>Inside Dynamic HTML</H1> </DIV> <P><EM>Inside Dynamic HTML</EM> teaches the Web developer how to create interactive and live Web pages.</P> </BODY> </HTML>
404 Часть IV. Содержание документа и связывание данных Элемент div баннера может содержать любой код HTML, включая сцена- рии. Все содержание будет скопировано в другой фрейм. Приведенный ниже документ с набором фреймов содержит код, который автоматически изменяет размер набора фреймов после загрузки банне- ра. Данный код изменяет размеры строк, устанавливая для свойства scrollHeight баннера значение высоты фрейма, так что фрейм баннера име- ет соответствующую высоту. <HTML> <HEAD> <TITLE> Набор фреймов баннера </TITLE> <SCRIPT LANGUAGE-"JavaScript”> function fixup() { // Автоматическое изменение размера фрейма баннера. document.all.FS.rows = window.frames.Banner.document.body.scrollHeight + ) window.onload = fixup; </SCRIPT> </HEAD> <FRAMESET ROWS="100, *" ID="FS" FRAMEBORDER=0> <FRAME NAME="Banner" SCROLLING=NO NORESIZE> <FRAME SRC="Banner.htm’*> </FRAMESET> </HTML> Данный набор фреймов изменяет размер строки заголовка для первого за- гружаемого документа, но не изменяет автоматически размер строки заго- ловка, когда пользователь переходит к другой странице, на которой установ- лен другой размер баннера. На такие страницы можно добавить код, кото- рый вызывает функцию fixup родительского окна для изменения размера строки заголовка. < Расширенные индексы и таблицы содержания Чаще всего наборы фреймов используются для отображения списка глав документа в одном фрейме и выбранной главы в другом фрейме. Приведен- ный ниже пример демонстрирует наиболее интересные случаи использова- ния наборов фреймов. Первый пример автоматически генерирует индекс якорей, а второй автоматически генерирует таблицу содержания документа. Индекс или таблица содержания лучше всего отображаются в равноправном фрейме.
Глава 13. Динамическое содержание 405 Первый пример определяет необходимость отображения индекса. Если до- кумент загружается внутри набора фреймов и равноправный фрейм имеет идентификатор menu, то документ отображает индекс в данном фрейме. В противном случае, документ открывает новое окно для отображения ин- декса. Второй пример включает аналогичный код, определяющий необхо- димость отображения таблицы содержания. Индексы ссылок и закладок Приведенный ниже код создает окно индекса, содержащее копии всех эле- ментов Anchor документа. Код использует свойства innerHTML всех якорей для копирования их содержания, поэтому изображения корректно воспро- изводятся в окне индекса. <HTML> ' ' ' ’ <HEAD> <TITLE> Автоиндексация </TITLE> <SCRIPT LANGUAGE^'JavaScript"> function setupindex() { // Открыть новое окно, var winindex = null; /* Если имеется набор фреймов и фрейм меню, то вывести в данном фрейме. В противном случае вывести в новом окне. */ if (window.parent != self} if (null != parent.menu) winindex = parent.menu; if (null == winindex} winindex = window.open("", "Index", "width=300; height=500“); // Запустить создание документа индекса. winindex.document.open(}; winindex.document.write("<HTML>"); winindex.document.write("<TITLE>Index</TITLE>"); // Определение базового HREF и базовой цели. • var baseHREF = null; var baseTarget = null; // Проверка, наличия тегов <BASE> в документе. " S • • var base = document.all.tags("BASE"); for (var i = 0; i < base.length; i++) ( // Извлечение базового HREF и цели, если она указана. if (null != base[i].href} baseHREF = based).href; if (null != base[i].target) baseTarget - based] .target; )
406 Часть IV. Содержание документа и связывание данных // Установка имени целевого окна в случае отсутствия базового HREF, if ((null == baseTarget) || ("" == baseTarget)) ( if ("> == window.name) window.name = "outputhere"; baseTarget = window.name; ) // В случае отсутствия базового HREF установить текущий путь, if ((null == baseHREF) || ('” == baseHREF)) ( baseHREF = location.protocol + location.pathname; } // Вывод базового HREF в окне, winindex.document.writein("<BASE TARGET=" + + baseTarget + + "HREF='" + baseHREF + ">"); winindex.document.writein("<Hl>Links</Hl>"); // Поскольку используется innerHTML, то изображения и расширенный HTML извлекаются автоматически. // Перечисление всех элементов Anchor; пропуск карт изображений, for (var i = 0; i < document.links.length; i++) { var el = document.links[i]; if ("A" == el.tagName) ( var hText = el.outerHTML; winindex.document.writein("<P>" + hText); ) > winindex.document.writeln("<Hl>Bookmarks</Hl>"); // Перечисление всех закладок. for (var i = 0; i < document.anchors.length; i++) ( var el = document.anchors(i]; if ("A" ~ el.tagName) ( var hText = el.innerHTML; winindex.document.writein( "<PXA HREF=T’ + el.name + + hText + "</A>"); > I winindex.document.close(); > window.onload = setupindex; </SCRIPT> </HEAD> <BODY> <HlxA NAME=”top">Auto Indexing</Ax/Hl>
Гпава 13. Динамическое содержание 407 <Н2хА NAME="links">Link Demonstrations</AX/H2> <P>The following links will appear in the link index:</P> <PxA HREF=“http://www.insideDHTML.com">Inside Dynamic HTML</A> <PxA HREF="http://www.microsoft.com">Microsoft*s Web Site</A> <P>Images also work: <PxA HREF=”http: //www. insideDHTML. com”xIMG SRO”open.gif"x/A> <P>Rich HTML anchors are automatically picked up: <PXA HREF=”http://www.insideDHTML.com">Inside <EM>Dynamic</EM> HTML</A> </BODY> </HTML> Таблица содержания Следующий пример, который сходен с кодом индексирования ссылок, ав- томатически нумерует все заголовки и создает ссылки на них в отдельном окне таблицы содержания. Предоставляет динамическому HTML возмож- ность перечислить заголовки и исключает необходимость перечисления их вручную при вставке нового заголовка. Если таблица содержания находится в отдельном окне, то окно закрывается, когда пользователь покидает данную страницу. <HTML> <HEAD> <TITLE> Манипулирование заголовками </TITLE> <SCRIPT LANGUAGE^"JavaScript”> // Переменная для таблицы содержания var winTOC = null; function setupHeaders() ( var levels = new Object; var level = 0; if (window.parent != self) if (null ’= parent.menu) winTOC = parent.menu; if (null == winTOC) winTOC = window.open("", "Index", "width=300; height=500"); winTOC.document.open() ; winTOC.document.write("<HTML>”); winTOC.document.writein("<TITLE>Contents</TITLE>"); // Запись обработчика события нажатия кнопки для // прокручивания элемента в окне.
408 Часть IV. Содержание документа и связывание данных winTOC.document.writein("<SCRIPT> function gotoHeader()” + "(if (event.srcElement.linkTo != null)" + "event.srcElement.linkTo.scrollIntoView(true)) </" + ”SCRIPT>"); winTOC.document.writein("<BODY ONCLICK='gotoHeader()1" + "STYLE='cursor:hand'" + "onmouseover='if (event.srcElement.tagName =" + "&quot;SPAN&quot;)" + "event.srcElement.style.textDecorationUnderline ” + "= true' onmouseout = " + "'event.srcElement.style.textDecorationUnderline ” + "= false winTOC.document.writein("<Hl>Contents</Hl>"); var level =0; • // Перечисление всех элементов Heading. for (var i = 0; i < document.all.length; i++) { var el = document.all[i]; var charl = el.tagName.substring(0, 1); ’ var va!2 = parseint(el.tagName.substring(1, 2)); if (("H" = charl) && (2 == el.tagName.length) && (va!2 > 0) && (val2 < 7)) ( // Установка вложенного или простого списка. if (val2 > level) for (; level < val2; level++) { if (levels[level] == null) levels [level] = 0; winTOC. document. writein ("<DL>") ; ) else if (level > val2) for (; level > val2; level—) ( levels[level — 1] = 0; winTOC.document.writein("</DL>”) ; levels[level — 1]++; var hText = document.all[i].innerText; winTOC.document.writein("<DT><SPAN>"); var strNum = ""; for (var iOut = 0; iOut < level; iOut++) { winTOC.document.write(levels[iOut].toString() + "."); strNum += levels[iOut] + } document.all[i].insertAdjacentText("afterBegin", strNum + " ");
Гпава 13. Динамическое содержание 409 winTOC.document.writein(" ” + hText + "</SPAN>"); // Добавляет свойство co ссылкой на заголовок. winTOC.document.all(winTOC.document.all.length - lJ.linkTo = el; > > winTOC.document.closed; ' } window.onload = setupHeaders; // Если содержание выводится во фрейме, то данный обработчик // события unload удаляется. window.onunload = new Function ("if (!winTOC.closed) winTOC.close()"); </SCRIPT> </HEAD> <BODY ONLOAD=”setupHeaders(); "> <Hl>Dynamic HTML Auto-Numbering</Hl> <P>A11 the headers are automatically numbered and a table of contents is generated.</P> <P>Below are sample headings to be numbered. <H2>Finds all the headers.</H2> <P>A11 done automatically!</P> <H2>Automatically fills in a heading number.</H2> <Hl>Better Performance and Less Maintenance</Hl> <H2>Just maintain the page.</H2> <H2>Don't worry about renumbering headings.</H2> <H3>Test header 3</H3> <H2>No need to maintain separate contents document.</H2> </BODY> </HTML> Вставка кода из данного документа в любую Web-страницу обеспечивает повышение ее интерактивных возможностей и упрощает навигацию. Дан- ный пример также демонстрирует необходимость правильной установки вложенности заголовков. Поскольку код обрабатывает некорректно вложен- ные заголовки, то результат будет более значительным, если правильно оп- ределить порядок заголовков. На рис. 13.4 показана работа приложения Table of Contents. Таблица содер- жания и нумерованные заголовки автоматически генерируются после за- грузки страницы.
410 Часть IV. Содержание документа и связывание данных IIП Automatic Table of Contents - Microsoft Internet Explotei ЯИЕЗ| [].,Ре G° .Fjv&ites Help . B9 Contents 1 Dynamic HTMLAuto | Numbering 1.1 Finds all the headers. 1.2 Automatically fills in a heading number 2 Better Performance and Less Maintenance ! 2.1 Just maintain the page. 2 2 Don't worry about renumbering headings. 2 2.1. Test header 3 2.3 No need to maintain separate contents document 1. Dynamic HTML Auto Numbering All the headers are automatically numbered and a table of contents is generated Below are sample headings to be numbered 1.1. Finds all the headers. All done automahcallyl 1.2. Automatically fills in a heading number. ft i ЦЕЛЕБЕН ' |. ' НК*.* 1 > 1 jM MyComputer Z/J Рис. 13.4. Таблица содержания и нумерованные заголовки
Г лава 14 Пользовательские операции выделения и редактирования В данной главе рассматривается объект TextRange, который используется для доступа к содержанию документа и манипулирования им. Динамический HTML определяет объектную модель, которая может манипулировать доку- ментом с помощью сценариев, аналогично текстовому редактору. Объект TextRange представляет возможности редактирования браузера и операции, которые составляют модель редактирования.. Используя объект TextRange, вы можете редактировать любой текст, а также манипулировать текстом, который пользователь выделил на экране. В данной главе рассмотрены следующие темы: □ Введение в объект TextRange. В этом разделе рассматривается объект TextRange, как он представляет текстовое содержание документа и его от- ношения со структурой документа. Кроме того, обсуждаются также неко- торые ограничения и неопределенности объекта TextRange. □ Программирование объекта TextRange. В данном разделе обсуждается пе- ремещение в документе и изменение его содержания с помощью свойств И методов объекта TextRange. □ Доступ к выделенной пользователем области. В разделе показано обраще- ние к выделенному пользователем тексту, одному из основных примене- ний объекта TextRange. Выделенным пользователем простым текстом и HTML-текстом можно манипулировать и изменять его. □ Выполнение команд. Динамический HTML представляет набор связанных с редактированием методов, которые представлены для документа и объ- екта TextRange. В разделе показано использование данных методов для запроса информации о документе и манипулирования внешним видом документа. Методы манипулирования документом используются для опо- средованного изменения HTML и получения требуемых эффектов. На- пример, для создания элемента Anchor на основе произвольного текста.
412 Часть IV. Содержание документа и связывание данных Введение в объект TextRange Ранее мы рассматривали изменение документа путем прямого манипулиро- вания индивидуальными элементами или таблицами стилей. Как таблицы глобальных стилей манипулируют стилем документа независимо от его структуры, так и объект TextRange манипулирует содержанием документа независимо от стиля и структуры. Данный объект предназначен для добав- ления внутренних и внешних свойств элементов с целью манипулирования динамическим содержанием, введенным в главе 13. Эти свойства элементов обеспечивают более надежный результат и их следует использовать в общем случае вместо объекта TextRange. Объект TextRange обеспечивает доступ к тексту, как большому буферу сим- волов. Рассмотрим следующий простой пример: <HTML> <BODY> <Hl>Welcome</Hl> <Н2>ТаЫе of Contents</H2> <UL> <LI>Chapter 1</LI> <LI>Chapter 2</LI> </UL> </BODY> </HTML> На рис. 14.1 показан текст данного документа, расположенный ниже дерева анализа. Символы, принадлежащие определенному элементу в дереве, нахо- дятся в сфере влияния данного элемента. Например, элемент chapter 1 на- ходится в сфере влияния первого элемента ы. Объекты TextRange могут быть созданы только специальными элементами, которые считаются владельцами редактирования текста (text edit owner). Владелец редактирования текста является элементом, который может соз- дать объект TextRange С ПОМОЩЬЮ метода createTextRange, таким образом предоставляя доступ к основному буферу. На данный момент только два типа элементов HTML могут функционировать в качестве владельцев редак- тирования текста в динамическом HTML: элемент Body является владельцем редактирования текста для всех воспроизводимых элементов, а элементы ввода, такие как input, Button и TextArea, являются владельцами редактиро- вания текста для своего содержания. Например, вы можете создать объект TextRange ДЛЯ предыдущего документа путем вызова метода createTextRange объекта body: var tr = document.body.createTextRange();
Гпава 14. Пользовательские операции выделения и редактирования 413 Рис. 14.1. Отношения между объектом TextRange И структурой документа После создания объекта TextRange можно легко получить доступ к любому элементу содержания внутри объекта. Первоначально весь текст, находящийся в области влияния владельца тек- ста, содержится в объекте TextRange. Например, объект TextRange в преды- дущем документе охватывает весь текст в элементе Body. Вы можете исполь- зовать методы объекта TextRange для изменения положения объекта с целью включения в область действия другого текста. Объект TextRange охватывает текст, над которым в данный момент производятся манипуляции или кото- рый изменяют. Сценарий может заменить охватываемый текст так же, как пользователь может выделить старый текст и набрать другой текст в тексто- вом редакторе. Ниже в разделе данной главы "Выполнение команд' вводятся методы манипулирования внешним видом документа, которые аналогичны выбору пользователем шрифта или изменения стиля текста в текстовом ре- дакторе. Объект TextRange разработан с большой степенью надежности и предназна- чен для автоматического приема произвольного HTML, внедряемого в до- кумент. Когда новый текст вставляется в объект TextRange, то HTML также вставляется в документ, аналогично тому, как пользователь выбирает коман- ду Paste (Вставить) из меню Edit (Правка) и вставляет произвольный текст. Данные операции являются мощными, но они не предназначены для пре- доставления разработчику возможности тщательного контроля документа. Напротив, разработчик может использовать данные операции для измене- ния документа на высоком уровне, не думая о конкретном коде HTML, ко- торый реализует данные модификации. Правила управления кодом HTML, которые генерируют данные операции, вероятно, будут изменены в следую- щей версии браузера Microsoft Internet Explorer. Поэтому объект TextRange не следует использовать, когда результат операции требует, чтобы HTML
414 Часть IV. Содержание документа и связывание данных принимал определенную форму. Вместо него следует использовать внутрен- ние и внешние свойства. Охватываемый текст Объект TextRange не определяет текст, который он охватывает, в терминах порядковых индексов символов начала и конца текстовой области. Он опре- деляет содержащийся в нем текст таким образом, при котором данный текст более свободно связан с положением в документе и может отражать измене- ния состояния документа. Например, если объект TextRange охватывает все содержание документа, а содержание расширяется или сокращается вследст- вие работы другого процесса, то объект TextRange автоматически отражает данное изменение и продолжает охватывать все содержание документа. Ограничения объекта TextRange Объект TextRange в настоящее время очень тесно связан с символами, что обусловливает неясности между объектом TextRange и структурой докумен- та. Во многих случаях в HTML по положению одиночного символа невоз- можно точно определить HTML-элемент, в области влияния которого нахо- дится символ, как показано ниже: <P>This is <BXI>bold and italic</I> text. </BX/P> В объекте TextRange данное содержание представлено как строка This is bold and italic text. Предком буквы ь в текстовом буфере является элемент italic (курсив), а предком элемента italic является элемент Bold (Полужирный). Символы слова “bold” и предшествующий ему пробел не содержат элемен- тов Bold, которые являются их прямыми предками. Используя свойство TextRange вы не можете вставить выделение полужирным шрифтом, или курсивом перед словом “bold”. Объект TextRange на данный момент осно- ван на одиночной точке выделения, которая может находиться перед буквой ь (что устанавливает полужирный курсив текста) или в пробеле после слова is (что не устанавливает выделение текста полужирным начертанием и кур- сивом). Объект TextRange не может вставить текст между тегами <в> и <х>. Для вставки текста между тегами <В> и <1> используйте методы insertAdjacentText и insertAdjacentHTML, введенные в главе 13. Данные методы могут вставить текст перед или после любого открывающего или закрывающего тега в теле документа. Программирование объекта TextRange В данном разделе вводятся свойства и методы манипулирования объектом TextRange. Методы позволяют сценариям манипулировать основным текстом почти так же, как пользователь мог бы редактировать его в текстовом редак- торе, выделяя текст и вводя или вставляя новый текст в документ.
Глава 14. Пользовательские операции выделения и редактирования 415 Создание объекта TextRange ' Как упоминалось выше, объект TextRange создается путем вызова метода createTextRange элемента, который является владельцем редактирования текста. Подобно свойствам динамического содержания объект TextRange не- доступен до тех пор, пока весь документ не будет проанализирован. В ходе анализа документа попытки создания объекта TextRange при помощи метода createTextRange будут неудачными. Поэтому перед использованием методов, которые возвращают объект TextRange, убедитесь, что документ полностью проанал изирован. Объект TextRange, возвращаемый методом createTextRange, должен быть на- значен переменной. В противном случае созданный в памяти объект TextRapge будет немедленно разрушен. Ниже показано, как правильно соз- дать объект TextRange: var tr = document.body.createTextRange(); Так создавать объект TextRange нельзя: document.body.createTextRange(); // Этот оператор ничего не делает. Единственная ситуация, когда не требуется назначать новый объект TextRange переменной, возникает в случае, если последовательность опера- ций может быть выполнена одним действием — например, если вы заменяе- те HTML, который представлен объектом TextRange: // Заменяет все содержание тела HTML, document.body.createTextRange().pasteHTML("<Hl>New Document</Hl>"); Свойство parentTextEdit Все элементы имеют свойство parentTextEdit, которое ссылается на вла- дельца редактирования текста, ответственного за содержание элемента. Ис- пользование данного свойства может обеспечить коду совместимость с бу- дущими версиями объектной модели. В настоящее время свойства parentTextEdit для большинства элементов в документе ссылаются на эле- мент Body. Элементы, находящиеся внутри элемента Button, являются един- ственными исключениями. Владельцем редактирования текста данных эле- ментов является элемент Button. Однако будущие версии объектной модели могут поддерживать большее количество элементов в качестве владельцев редактирования текста. При создании объекта TextRange для элемента сле- дует использовать его свойство parentTextEdit для идентификации владель- ца редактирования текста, и код должен будет* работать даже при смене вла- дельца редактирования текста. Приведенный ниже код иллюстрирует дан- ный метод:
416 Часть IV. Содержание документа и связывание данных //el представляет объект элемента в документе, var tr; if (!el.isTextEdit) . ' ’ tr = el.parentTextEdit.createTextRangeO; : else tr = el.createTextRange(); Каждый элемент в теле документа представляет свойство isTextEdit, кото- рое указывает, является ли элемент владельцем текстового редактирования. Приведенный выше код использует элемент el для создания объекта TextRange, если el является владельцем текстового редактирования. В про- тивном случае код использует владельца редактирования текста предка эле- мента el. Приведенная ниже строка определяет, что элемент Body является владельцем редактирования текста: alert(document.body.isTextEdit); // true; элемент Body является // владельцем редактирования текста. Представление содержания документа Объект TextRange содержит свойства text и htmlText, которые обеспечивают доступ к форматированному и неформатированному тексту документа. Свойство text представляет текст документа без разметки HTML. Это свой- ство доступно для чтения/записи и может быть использовано для замены неформатированного содержания. Свойство text сходно со свойством outerText объектов элемента тем, как оно представляет содержание доку- мента и типами значений, которые могут быть ему присвоены. Свойство htmlText представляет текст вместе с разметкой HTML. Данное свойство представляет HTML так же, как свойство outerHTML, но в отличие . ОТ свойства outerHTML свойство htmlText доступно только для чтения. Для назначения нового HTML объекту TextRange следует использовать метод ' pasteHTML. Назначение нового HTML обрабатывается отдельным методом, поскольку не является симметричным при чтении текущего HTML. Значение, которое вы вставляете в текстовую область, используя метод : pasteHTML, может не совпадать со значением, которое впоследствии возвра- щается свойством htmlText. Объект TextRange может изменить или очистить вставляемый HTML, и код HTML может даже повлиять на содержание за Границами объекта TextRange. Метод pasteHTML разработан для вставки действительного HTML. При вызо- ве метода pasteHTML для определенного элемента вставляемый фрагмент бу- дет находиться внутри области действия данного элемента и должен быть действительным кодом HTML внутри данной области действия, в соответст- вии с определением типа документа (DTD). Браузер попытается удалить не-
Гпава 14. Пользовательские операции выделения и редактирования 417 действительный код HTML и может расширить HTML за границы, исходно установленные объектом TextRange. При возвращении метода pasteHTML объект TextRange обновляется, чтобы включить вставленный текст в ’свою область действия. Сравнение свойств text и htmIText Главное преимущество использования свойства text по сравнению с htmIText и pasteHTML заключается в обработке компонентов, представляю- щих угловые скобки. Когда вы присваиваете значение свойству text, это значение анализируется как неформатированный HTML, так что угловые скобки автоматически заменяются на соответствующие компоненты. На- пример, <is заменяется на sit,-. При чтении свойства text компоненты воз- вращаются в виде буквенных значений. При вставке нового текста в текстовую область с помощью метода pasteHTML текст анализируется как код HTML, поэтому любые угловые скобки интер- претируются как часть тегов HTML. Если необходимо вставить угловую скобку в текст, то вы должны заменить соответствующий компонент вруч- ную. Когда вы используете свойство htmIText для извлечения текстовой об- ласти, то все угловые скобки в тексте представлены в виде компонентов. Например, <is возвращается как &it;. Пробел Свойство text объекта TextRange представляет пробел так, как он воспроиз- водится на экране, а не в основном документе. В большинстве случаев в HTML дополнительные пробелы игнорируются. Например, если HTML- документ использует три пробела между словами, то текст будет отображать- ся с одним пробелом между каждым словом. Кроме того, возвраты каретки внутри HTML-документа игнорируются. Теги блока определяют разрывы строки. Исключением из данных правил являются элементы pre и хмр, в которых существующие пробелы сохраняются и поддерживаются любые пробелы, которые будут вставлены позднее. Плавающие закрывающие теги Нельзя закрыть элемент в документе до закрывающего тега. Предположим, что в документе находится элемент Bold: <B>This is bold text.</B> Если объект TextRange используется для вставюи нового закрывающего тега </в> между словами bold и text, то новый тег не станет закрывающим тегом . для элемента Bold.
418 Часть IV. Содержание документа и связывание данных Метод pasteHTML не вставляет фрагмент в дерево. Фрагмент проверяется на соответствие DTD, которое определяет, что дополнительные закрывающие теги будут игнорироваться. Поэтому вставка тега </в> не окажет влияния на текст или дерево документа. Недействительная область действия Некоторые HTML-элементы могут быть действительными только внутри области действия других элементов. Например, считается, что элемент td находится в элементе tr внутри таблицы Table. В главе 7 описываются пра- вила анализатора для обработки элементов в исходном документе, которые не находятся внутри действительной области действия. Многие правила также применимы к HTML, который вставляется с помощью объекта TextRange. Например, приведенный ниже код пытается заменить тело доку- мента на один элемент td: var tr = document.body.createTextRange(); tr.pasteHTML("<TD>Cell outside any table or row</TD>"); В данном примере содержание вставляется в документ, но окружающие теги <td> игнорируются, поскольку не определена действительная таблица. Нет гарантии, что обработка этой ошибки будет поддержана в последующих вер- сиях динамического HTML. Поэтому для получения предсказуемых резуль- татов следует вводить действительный фрагмент HTML. Связь объекта TextRange со структурой документа Метод parentElelment объекта TextRange сообщает об отношениях между текстовой областью и структурой документа. Данный метод возвращает по- следний элемент в дереве анализа, который влияет на всю область текста. Как показано на рис. 14.1, на каждый символ в текстовой области влияет конечный узел (leaf node, узел без дочерних элементов). Когда объект TextRange представляет символ, то его метод parentEiement возвращает ко- нечный узел, влияющий на символ. Когда объект TextRange представляет область символов, то его метод parentEiement является узлом, который воз- действует на всю область. Когда объект TextRange сначала создается для элемента Body, то он представляет весь текст, так что его метод parentEiement ЯВЛЯСТСЯ обычно СЭМИМ Элементом Body. Позиционирование объекта TextRange Изначально объект TextRange заключает в себе весь текст, который находит- ся в области влияния владельца редактирования текста, в котором он был создан. Например, вызов метода createTextRange элемента Body возвращает текстовую область, которая включает все содержание тела.
Глава 14. Пользовательские операции выделения и редактирования 419 Набор методов объекта TextRange изменяет положение объекта TextRange для охвата различного текста. Основная архитектура объекта TextRange не связа- на с порядковыми индексами символов, которые он охватывает в текстовом буфере. Нельзя непосредственно манипулировать конечными точками тек- стовой области, назначая их новым символьным индексам. Вместо этого методы перемещения объекта TextRange изменяют положение объекта для осуществления операций с текстом. Они могут позиционировать объ- ект TextRange для охвата всех символов, слов, предложений, владельца ре- дактирования текста, элемента или точки на экране. Данные методы не приводят к перемещению текста по документу. Ниже перечислены методы позиционирования объекта TextRange: □ expand(unit) □ moveToElementText(element) □ moveStart(unit, count) □ moveToPoint(x, y) □ collapse(start) □ move(unit, count) □ moveEnd(unit, count) □ findText(string, count, flags) Для изменения положения объекта TextRange предназначены методы setEndPoint И moveToBookmark. Метод setEndPoint дополняет метод compareEndPoints. Эти методы обсуждаются ниже в разделах данной главы "Управление объектами TextRange "и "Манипулирование закладками". Методы expand и collapse Метод expand расширяет объект TextRange для полного охвата символа, сло- ва, предложения или всего текста владельца редактирования текста, в кото- ром он был создан. Например, если объект TextRange охватывает часть сло- ва, вызов его метода expand с параметром word приводит к распространению метода на все слово. В случае успеха метод expand возвращает true. Метод collapse выполняет обратную операцию, помещая открывающие и закрывающие маркеры объекта TextRange вместе в качестве точки вставки. Необязательный параметр определяет, будет ли помещена точка вставки в ' начале или конце текущей области. Значение по умолчанию равно true, что приводит к установке точки вставки в начало. Метод moveToElementText Метод moveToElement размещает объект TextRange для охвата текста, нахо- дящегося в области действия данного элемента. Несмотря на согласован- ность данного метода с поведением объекта TextRange нет гарантии, что присвоение значения объекту TextRange, размещенному с использованием moveToElementText, приведет к изменению тоЛько содержания элемента. Ес- ли требуется прямо изменить содержание элемента, то следует использовать внутренние и внешние свойства, введенные в главе 13.
420 Часть IV. Содержание документа и связывание данных Метод moveToElementText применяется для перемещения по документу с це- лью выполнения последующих манипуляций, например, анализа первого слова всех заголовков. Объект TextRange может быть ле^ко перемещен в элемент без анализа строк кода. В следующем разделе рассматриваются не- которые методы выполнения этой задачи. Методы move, moveStart и move End Методы move, movestart и moveEnd перемещают объект TextRange на опреде- ленное расстояние. Методы movestart и moveEnd изменяют положение от- крывающих и закрывающих маркеров объекта TextRange. Метод move пере- мещает открывающий маркер объекта TextRange на определенное расстояние и сжимает объект до точки вставки. Все три метода принимают два одинаковых параметра. Первый параметр определяет необходимость перемещения слова, символа или предложения в конец текстового потока. Второй параметр определяет расстояние переме- щения. Второй параметр может иметь положительное или отрицательное значение, что указывает направление перемещения: вперед или назад. Пер- вый параметр может иметь одно из перечисленных в табл. 14.1 значений: Таблица 14.1. Значения первого параметра методов move, moveStart И moveEnd Единица Определение character Перемещает на определенное число символов word Перемещает на определенное число слов sentence Перемещает на определенное число предложений textedit Перемещает на определенное число элементов редактирования текста Методы move, moveStart И moveEnd возвращают число, равное расстоянию перемещения. Например, если вы пытаетесь переместить 200 слов в доку- менте, содержащем 100 слов, то метод move поместит объект TextRange в по- следнее слово в данном документе и возвратит число перемещенных слов. Для проверки успешности проведения операции сравните возвращаемое значение с числом перемещенных слов: if (200 == tr.move("word", 200)) ( / / Успешно! ) else ( // Невозможно переместить 200 слов.
Гпава 14. Пользовательские операции выделения и редактирования 421 Метод move помещает объект TextRange как точку вставки между двумя сим- волами. Например, вызов метода move для перемещения вперед трех слов помещает объект TextRange между третьим и четвертым словами. В данном случае свойство text вернет пустую строку. Присвоение значения свойству text или вызов метода pasteHTML приведет к вставке текста в данную точку документа. Методы movestart и moveEnd изменяют положение открывающего и за- крывающего символов. Например, данный метод может быть использован для расширения выделения с четырех до пяти слов, путем перемещения исходной позиции вперед или конечной позиции назад. Приведенный ниже фрагмент кода демонстрирует получение первого слова элемента в до- кументе: . function firstWord(myElement) ( // Obtain a TextRange object. var tr = document.body.createTextRange(); 11 Перемещает объект TextRange. // myElement представляет элемент в документе. tr.moveToElementText(myElement); // Сворачивает объект TextRange к началу элемента. tr.collapse(); if (tr.moveEndC'word", 1)) return tr.text; else return ) Следующий пример демонстрирует подсчет числа слов в документе. Данный код может быть легко изменен для подсчета других единиц путем изменения первого параметра в методе move. function countwords() ( var tr = document.body.createTextRange(); var intCount = 0; // Сворачивает объект TextRange к началу документа. tr.collapse(true); while (tr.move("word”, 1)) intCount++; return intCount-1; , ) При перемещении слова или символов все элементы, представляющие объ- ект, включая изображения, внутренние элементы управления и так далее, являются одной единицей.
422 । Часть IV. Содержание документа и связывание данных ( Примечание ) Способы перемещения объекта TextRange, которые применяются в данных методах, можно сравнить со способами перемещения или изменения выделе- ния текста с помощью сочетания клавиш в популярных текстовых процессорах, таких как Microsoft Word. Например, метод move изменяет положение объекта TextRange как точки вставки, аналогично изменению положения курсора в тек- стовом процессоре с помощью клавиш со стрелками <Right> и <Left>. Нажатие клавиши со стрелкой перемещает курсор на один символ. Нажатие клавиши со стрелкой при нажатой клавише <Ctrl> перемещает курсор на одно слово. Мето- ды moveStart и moveEnd разворачивают или сворачивают текст, охватывае- мый объектом TextRange, аналогично тому, как с помощью сочетания клавиш изменяется размер области выделенного текста. Нажатие клавиши со стрелкой <Right> или <Left> при нажатой клавише <Shift> приводит к расширению или сужению области выделения на один символ в выбранном направлении. Удер- живание нажатыми клавиш <Shift> и <Ctrl> приводит к изменению области вы- деления на одно слово одновременно. Метод moveToPoint Метод moveToPoint принимает в качестве аргумента точку в клиентской об- ласти на экране, определяет элемент, который будет выведен на экран в данной точке и помещает объект TextRange в качестве точки вставки дан- ного элемента. Этот метод при использовании в обработчике событий мыши для определения области текста, над которой находится указатель мыши, обеспечивает большую точность, чем свойство srcElement, которое возвра- щает элемент, на котором находится указатель мыши. Приведенный ниже код обработчика событий мыши отображает в строке состояния слово, над которым находится указатель мыши: function doMouseMove() ( var tr = document.body.createTextRange(); tr.moveToPoint(event.clientx, event.clientY); /f Охватывает все слово, над которым находится указатель мыши, tг.expand("word”); window.status = tr.text; ) document.onmousemove = doMouseMove; Метод findText Метод findText осуществляет поиск выбранной строки в документе. Диа- логовые окна Find (Найти) браузера используют метод findText и могут продемонстрировать гибкость данного метода. Метод findText использует три параметра. Первый параметр представляет строку, которую требуется найти в документе. Второй параметр представляет число символов, которые следует искать в документе. Значение должно быть
Гпава 14. Пользовательские операции выделения и редактирования 423 положительным для поиска в прямом направлении или отрицательным для поиска в обратном направлении. Третий параметр определяет, должно ли совпадать слово целиком и следует ли учитывать регистр: значение 2 задает совпадение слова целиком, 4 — учитывает регистр и 6 — устанавливает оба параметра. Управление объектами TextRange Существуют методы для клонирования объекта TextRange, сравнения двух объектов TextRange и для позиционирования одного объекта TextRange отно- сительно другого. Метод duplicate Метод duplicate создает копию объекта TextRange, из которого он был вы- зван. Например, приведенный ниже фрагмент кода создает копию объекта TextRange С именем tr: var tr2 = tr.duplicate(); Методы inRange и isEqual Метод inRange определяет, находится ли указанная текстовая область внутри области действия объекта TextRange, из которого был вызван данный метод: • . alert(tr2.inRange(tr)); // true; tr находится внутри tr2. Метод isEqual сравнивает два объекта TextRange и определяет, охватывают ли они один и тот же текст. Метод необходим, потому что объекты TextRange, представляющие одну текстовую область, могут быть, тем не ме- нее, различными объектами, так что прямое их сравнение не будет работать. Приведенный ниже код демонстрирует правильный и неправильный способ проверки, охватывают ли два объекта один текст: // Установка примера. var tr = document.body.createTextRange(); var tr2 = tr.duplicate(); // Неправильный способ сравнения текстовых областей: alert(tr == tr2); // false; данные два объекта различны. // Правильный способ сравнения текстовых областей: alert(tr.isEqual(tr2)); // true Методы compareEndPoints и setEndPoint Метод compareEndPoints сравнивает два объекта TextRange и выясняет, сов- падают ли их начальные и конечные позиции. Метод setEndPoint устанав-
424 Часть IV. Содержание документа и связывание данных ливает начальную и конечную позиции объекта TextRange в начальную и конечную позиции другого объекта TextRange. Оба метода принимают два параметра. Начальная и конечная позиции объекта TextRange, из которого был вызван метод, сравниваются или устанавливаются в начальные и ко- нечные позиции объекта TextRange, который определен во втором парамет- ре. Первый параметр может быть равен любому значению в табл. 14.2, кото- рое определяет используемые положения. Таблица 14.2. Значения первого параметра методов compareEndPoints ИsetEndPoint Значение Описание StartToStart Устанавливает или сравнивает начальную позицию текущего объекта TextRange с начальной позицией объекта TextRange, определенного во втором параметре StartToEnd Устанавливает или сравнивает начальную позицию текущего - объекта TextRange с конечной позицией объекта TextRange, определенного во втором параметре EndToEnd Устанавливает или сравнивает конечную позицию текущего объекта TextRange С конечной позицией объекта TextRange, определенного во втором параметре EndToStart Устанавливает или сравнивает конечную позицию текущего объекта TextRange С начальной позицией объекта TextRange, определенного во втором параметре Приведенная ниже функция определяет, будет ли продолжен объект trDest после окончания объекта trsrc: function continues(trSrc, trDest) ( return trSrc.compareEndPoints("EndToStart", trDest); ) Прокручивание области просмотра Обработка объектов TextRange производится целиком в памяти. Изменение свойств text и htmlText в объекте TextRange не приводит к прокручиванию документа. Для прокручивания текста, охватываемого объектом TextRange, следует использовать метод scrollintoview, который поддерживают все эле- менты. Для данного метода должен быть указан одиночный необязательный параметр, который определяет необходимость прокручивания текста в объ- екте TextRange в верхнюю (значение true) или нижнюю (значение false) часть экрана.
Глава 14. Пользовательские операции выделения и редактирования 425 Манипулирование закладками Закладка определяет положение объекта TextRange в тексте, аналогично за- кладке HTML, которая определяет местоположение в документе. Вы можете использовать метод getBookmark объекта TextRange для сохранения записи текущего положения объекта как закладки, а его метод moveToBookmark — для возвращения сохраненного положения. Метод getBookmark возвращает закладку как строковое значение. Подобно объекту TextRange закладка не фиксирует начальное и конечное положение как символьные индексы. Закладка представляет собой строку, которая со- держит информацию о положении в зашифрованной форме. Данной стро- кой нельзя манипулировать напрямую и ее следует использовать только с методами TextRange. Метод moveToBookmark принимает строку закладки как параметр и располага- ет объект TextRange в соответствии с закладкой. Данный метод возвращает логическое значение, которое указывает успешность проведенной операции. Можно обеспечить совпадение положений двух объектов TextRange путем вызова метода первого объекта moveToBookmark и передачи ему закладки, возвращенной методом getBookmark второго объекта. Однако для копирова- ния закладки проще использовать метод duplicate. Внедренные объекты Внедренные объекты представляют собой HTML-элементы, которые явля- ются внутренними элементами управления, элементами object, изображе- ниями и так далее. Каждый внедренный о&ьект представлен пробелом в объекте TextRange. Чтобы определить, представляет ли пробел в объекте TextRange внедренный объект, используйте другой объект TextRange, кото- рый охватывает только пробел и примените метод parentElement. Для добавления внедренного объекта в объект TextRange вставьте соответст- вующий HTML в документ, используя метод pasteHTML. После выполнения назначения и анализа HTML, текст в объекте TextRange автоматически об- новляется с учетом пробела для представления вновь подтвержденного вне- дренного объекта. Выбор текстовой области Метод select о&ьекта TextRange выделяет выбранный пользователем текст, находящийся в области действия данного объекта. Когда выбран о&ьект TextRange, охватываемый им текст выделен на»экране. Последующее расши- рение области действия объекта TextRange не приводит к расширению об- ласти выделения, если только вы не вызвали метод select снова.
426 Часть IV. Содержание документа и связывание данных Доступ к выделенной пользователем области Операция выделения пользователем текста непосредственно связана с объектом TextRange. Свойство selection документа используется для ссылки из сцена- рия на о&ьект, который представляет текущее выделение в браузере. Данный объект selection также представляет свойство type, которое возвращает тип выбора: None при отсутствии выбора и Text для выделения текста. Когда текст выделяется на экране, то метод createRange объекта выделения возвращает объ- ект TextRange, который охватывает выбранный текст. Перемещение данного объекта TextRange не приведет к изменению области выделенного текста, но изменения в тексте, произведенные объектом TextRange, безусловно, будут от- ражены на экране. Чтобы привести область выделения на экране в соответствии С объектом TextRange, МОЖНО ВЫЗВЭТЬ метод select Объекта TextRange. Напри- мер, приведенный ниже код использует объект TextRange для расширения об- ласти выделения на экране на одно слово: if ("Text" = document.selection.type) { var tr = document.selection.createRange(); // Переместить конечную позицию для включения одного дополнительного // слова. tr.moveEnd("word", 1); // Снятие выделения области, tr.select(); } else alert("No text is selected."); Всегда следует проверять тип выделения перед выполнением каких-либо манипуляций, потому что браузер поддерживает второй тип объекта, с име- нем ControiRange для выбора многочисленных элементов управления. Поскольку на данный момент невозможно выделить многочисленные эле- менты управления во время просмотра документа, то объект Controlobject не обсуждается. Выполнение команд Объектная модель динамического HTML представляет набор методов, кото- рые позволяют непосредственно выполнять пользовательские операции в области или документе. Данные операции соответствуют различным дейст- виям, которые пользователь может выполнять с текстом. Например, имеют- ся команды для выделения или снятия выделения текста полужирным на- чертанием, аналогично кнопке переключения Bold (Полужирный) в текста-
Глава 14. Пользовательские операции выделения и редактирования 427 вом редакторе. Эти команды изменяют основной HTML для достижения требуемого результата. На данный момент все манипуляции стилем обеспе- чиваются внедрением разметки HTML в документ. При этом не гарантиру- ется, что команды будут выполнять манипуляции стилем в будущих версиях браузеров так же. Единственное, что можно гарантировать — видимый ре- зультат действия команд будет одинаков. Данные команды позволяют странице манипулировать стилем и содержани- ем документа, не заботясь о структурных правилах HTML. Например, при вызове команды Bold генерируется соответствующий код HTML. Также поддерживаются команды для выполнения других базовых пользовательских операций, таких как вырезание и копирование текста, добавление элементов управления в фиксированные области и отмена последней операции. Объекты TextRange и объект document представляют ряд методов для выпол- нения и создания запроса состояния команд. Данные методы разделены на две категории: методы, которые возвращают состояние команды, и методы, которые выполняют команду. Для определения состояния команды доступ- ны шесть методов, которые перечислены ниже: □ queryCommandSupported(cmdID) □ queryCommandEnabled(cmdID) □ queryCommandState(cmdID) О queryCommandlndeterm (cmdID) □ queryCommandText(cmdID, text) О queryCommandValue(cmdID) Данные методы более понятны в контексте пользовательского интерфейса Текстового редактора. Методы queryCommandSupported И queryCommandEnabled возвращают логические значения, сообщая о поддержке и доступности вы- бранной команды. Если команда отключена, то ее выполнение не оказывает никакого влияния на документ. Метод querycommandstate определяет, будет ли указанная команда выполнена на объекте. Например, вызов данного ме- тода с параметром Boid возвращает true, если объект охватывает текст с по- лужирным начертанием, false в противном случае и null, если метод не может определить состояние. Метод queryCommandlndeterm проверяет дос- тупность состояния команды. Например, если объект TextRange охватывает полужирный и обычный текст, то данный метод возвращает true, поскольку действительное полужирное состояние недоступно. Методы queryCommandText И queryCommandValue обеспечивают дальнейшую информацию о команде. Метод queryCommandText возвращает короткую строку меню или более длинную строку достояния, которая описывает функцию. Поскольку текст в этих строках может изменяться в различных браузерах, следует написать код, который не полагается на определенную возвращаемую строку. Метод querycommandvalue возвращает реальное значе-
428 Часть IV. Содержание документа и связывание данных ние команды. Например, вызов данного метода с параметром FontName воз- вращает имя шрифта. Приведенные выше методы не оказывают влияния на документ. Они просто возвращают информацию о текущем состоянии. Для взаимодействия с до- кументом представлены перечисленные ниже методы: 3 execCommand(cmdlD [, displayUI] (, value]) 3 execCommandShowHelp(cmdlD) Метод execCommand выполняет команду. Аргумент cmdlD представляет необ- ходимую команду, которая должна быть вызвана. Необязательный параметр displayui определяет необходимость отображения или скрытия соответст- вующего пользовательского интерфейса. По умолчанию связанный пользо- вательский интерфейс не отображается. В некоторых случаях обход пользо- вательского интерфейса потенциально опасен. Поэтому аргумент displayui игнорируется и всегда отображается пользовательский интерфейс. Напри- мер, перед выполнением команды print (Печать) будет выведено окно с со- общением для пользователя. Атрибут value указывает значение для коман- ды. Метод execCommandShowHelp отображает файл справки, если он поддер- живается для определенной команды. Приведенный ниже код, который анализирует документ для определения числа отображаемых шрифтов, иллюстрирует использование метода queryCommandValue: <SCRIPT LANGUAGE-”JavaScript"> function walkDocument() { var fonts = new Array(); var tr = document.body.createTextRange(); tr.collapse(); while (tr.moveEnd("character", 1)) { var val = tr.queryCommandValue("FontName”); if (null == fonts[val]) { fonts[val] = true; fonts.length++ ) tr.collapse(false); ) var settings = "Total Fonts: " + fonts.length + "\n"; for (var font in fonts) ( settings += " " + font + "\n"; ) alert(settings); } </SCRIPT> На прилагаемом компакт-диске находится список всех доступных команд и типов значений, которые они принимают и возвращают.
Глава 15 .1. в У . '> > .. . _ Связывание данных с помощью HTML До появления связывания данных доступ к данным на Web-страницах про- изводился на низкой скорости. (Скорость доступа в Internet уменьшалась по мере роста трафика — особенно, если при использовании модема со скоро- стью передачи данных 28,8 Кбит/с.) Скорость отображения страниц, кото- рые обращались к данным, была низкой. Это было обусловлено большей частью тем, что серверы не только содержали Web-страницы, но также об- служивали доступ к базам данных и объединение данных со страницами для создания законченной HTML-страницы для клиента. Более того, поскольку страница передавалась клиенту, то отсутствовал способ разделения между данными и кодом HTML, в котором они содержались. В результате, когда пользователю требовалось выполнить манипуляции с данными (например, чтобы выполнить сортировку в другом порядке), то ему приходилось обра- щаться на сервер для повторного доступа к тем же данным, их форматиро- вания и передачи новой страницы клиенту. Серверу приходилось снова пе- редавать клиенту те же данные, внедренные в HTML-страницу. Некоторым серверам также требовалось поддерживать состояние клиента, чтобы гаран- тировать согласованное отображение данных на экране пользователя. Все это приводило к тому, что работа пользователя напоминала работу термина- ла мэйнфрейма. К счастью, все это в прошлом. Рассмотрим связывание данных (data binding). Связывание данных является элементом динамического HTML, позволяющим решать перечисленные проблемы. Связывание данных поддерживает различие между данными и кодом HTML, который отображает их. Данные передаются клиенту асин- хронно и воспроизводятся асинхронно по мере поступления, подобно по- степенно выводимому на экран изображению в формате GIF. Клиент может разделять данные и выполнять манипуляции*такие как сортировка, на ло- кальном клиентском компьютере. При этом не требуется обмен данными с сервером. Такая автономия уменьшает число обращений на сервер и объем
430 Часть IV. Содержание документа и связывание данных передаваемых данных. Web-страницы, построенные с использованием свя- зывания данных, отображают данные быстрее, снимают нагрузку формати- рования с сервера и обеспечивают более интерактивный и оперативный ре- жим работы, исключая длительные паузы ожидания при загрузке страниц. Цель данной главы заключается в предоставлении необходимой информа- ции для построения HTML-страницы с использованием связывания данных, а также для установки ссылок при построении страниц со связыванием данных. В главе рассмотрены следующие темы: □ Что такое связывание данных? Связывание данных является концепцией, введенной в динамическом HTML. В этом разделе дано определение термина связывание и вводятся концепции, которые будут рассмотрены в остальных частях данной главы. □ Архитектура связывания данных. В этом разделе обсуждаются три компо- нента архитектуры связывания данных: объекты источника данных, HTML-расширения связывания данных и агент связывания и повторения. Исходные объекты данных поставляют данные на Web-страпицы и ин- капсулируют функции передачи, определения, манипулирования и дос- тупа к сценариям. HTML-расширения связывания данных являются ат- рибутами, которые могут быть включены в HTML-элементы. Элементы, которые включают атрибуты связывания данных, называются потребите- лями данных (data consumers). Атрибуты определяют исходный объект данных, который поставляет данные элементу. Агент связывания и по- вторения распознает исходные объекты данных и потребителей данных на Web и синхронизирует передачу данных между элементами HTML и источником данных. □ Потребители данных: HTML-элементы. Большое количество HTML-эле- ментов поддерживает связывание данных. В разделе представлен список данных элементов и дано объяснение их использования для отображения и предоставления пользователю возможности взаимодействия с данными, поставляемыми объектом источника данных. В данном разделе также представлены примеры, которые демонстрируют связывание всех под- держиваемых HTML-элементов. □ Построение базовых страниц с помощью связывания данных. В данном разделе обсуждается три базовых типа связывания: связывание текущей записи, связывание таблицы с повторением и связывание таблицы с разбие- нием. Связывание текущей записи отображает данные из текущей записи в связанных элементах. Для установки другой текущей записи в наборе записей можно использовать сценарий. Когда новая запись становится текущей, то связанные элементы обновляются для отображения данных из этой записи. Связывание таблицы с повторением позволяет разработ- чику многократно использовать набор HTML-элементов, называемых
Глава 15. Связывание данных с помощью HTML 431 шаблоном, для построения таблицы, которая отображает все строки в на- боре данных. Связывание таблиц с разбиением аналогично связыванию таблицы с повторением, что позволяет разработчику ограничить число записей, отображаемых в таблице. Таблицу с разбиением можно предста- вить как окно в наборе записей. Используя сценарии, разработчик может затем перемещать это окно в наборе данных для отображения дополни- тельных данных. □ Написание сценариев, использующих связывание данных. Как часть функ- циональных возможностей связывания данных для написания приложе- ний разработчикам Web-страниц предоставляется расширенная модель событий. События предназначены для проверки, перемещения записей и асинхронной передачи данных. В разделе также описаны основы доступа к данным из объекта источника данных с использованием ADO (ActiveX Data Objects — объекты данных ActiveX). □ Дополнительные возможности. В этом разделе приведен краткий обзор ряда дополнительных возможностей связывания данных, включая обнов- ление данных, свойство recordNumber и доступ объектной модели к атри- бутам связывания данных. В этом разделе обсуждается преобразование Web-страницы в приложение клиент/сервер путем активизации обновле- ния данных. Свойство recordNumber, доступное из любого элемента в таб- лице с повторением и разбиением, позволяет разработчику Web-стра- ницы легко определять запись из объекта источника данных, с которой связан элемент. В остальной части данной главы обсуждается добавление, удаление и модификация атрибутов связывания данных элементов с ис- пользованием объектной модели динамического HTML. Что такое связывание данных? Прежде чем рассматривать три компонента архитектуры связывания данных, определим термин связь (binding). В упрощенной форме связывание пред- ставляет собой отношения между данными, поставляемыми объектом ис- точника данных, и HTML-потребителем данных. Данное отношение назы- вается связью, потому что значение элемента данных (который называется datem, что является сокращением от data item — элемента данных) синхро- низировано между клиентом и сервером. Когда HTML-потребитель данных (например, текстовое окно HTML) модифицирует элемент данных, то мо- дифицированный элемент данных сохраняется в объекте источника данных. Напротив, если объект источника данных изменяет значение данных, то мо- дифицированный элемент данных отправляется потребителю данных. Путем дальнейшего обобщения многочисленные потребители могут быть связаны с одним элементом данных, и все значения всех потребителей будут синхро- низированы со значением, указанным объектом источника данных. Значе-
432 Часть IV. Содержание документа и связывание данных ния в объекте источника данных связаны со значениями в одном или боль- шем количестве потребителей данных. Доступны два различных стиля связывания: связывание текущей записи (current record binding) и связывание таблицы с повторением (repeated table binding). Связывание текущей записи использует HTML-элементы для ото- бражения данных из текущей записи в наборе записей. В качестве текущей могут быть установлены различные записи. В таком случае элементы обнов- ляются динамически для отображения данных в записи. Связывание табли- цы с повторением позволяет определить набор связанных элементов, назы- ваемых шаблоном, который повторяется один раз для каждой записи в наборе записей. Разработчики Web-страниц также имеют возможность огра- ничения числа записей, повторяющихся в таблице. Этот элемент называется разбиением таблицы. Разбиение таблицы и два стиля связывания будут подробно рассмотрены ниже в разде- ле данной главы "Построение базовых страниц с использованием связывания данных". Архитектура связывания данных Архитектура связывания данных состоит из трех основных компонентов: □ Объекты источников данных □ HTML-расширения связывания данных, которые определяют потребите- лей данных □ Агент связывания и построения Объекты источников данных поставляют данные на страницу, а HTML- потребители данных отображают данные и обеспечивают взаимодействие пользователя с данными. Агент связывания и повторения обеспечивает под- держку стилей связывания. Дополнительно, агент связывания и повторения отвечает за синхронизацию всех связей с одиночным элементом данных, когда пользователи модифицируют данные на странице. Объекты источников данных Объекты источников данных обеспечивают открытую архитектуру для по- ставки данных на Web-страницу. Объекты источников данных внедряются в Web-страницу при помощи тегов <applet> или <object>, как показано ниже: <OBJECT ID="stocklist" WIDTH="0" HEIGHT="0" CLASSID="clsid:333C7BC4-46OF-11DO-BCO4-OO8OC7O55A83"> <PARAM NAME="DataURL" VALUE="stockdata.txt"> <PARAM NAME=,,FieldDelim” VALUE=" | "> <PARAM NAME="TextQualifier" VALUE=""> <PARAM NAME="UseHeader" VALUE="true"> </OBJECT>
Глава 15. Связывание данных с помощью HTML 433 После вставки объекта источника данных на страницу могут быть определе- ны потребители данных для отображения данных и взаимодействия с поль- зователем. Объекты источника данных могут быть реализованы во множестве языков программирования, включая Java, Microsoft Visual Basic и Microsoft Visual C++. Объекты источников данных отвечают за четыре главные функции доступа к данным: □ Обмен данных со страницей. Объекты источников данных должны реали- зовать механизмы извлечения данных для HTML-страницы. Объекты ис- точников данных ответственны исключительно за передачу данных кли- енту и, возможно, за передачу модификаций данных клиентом обратно на сервер. Они могут передавать данную информацию в любом подходя- щем режиме — используя HTTP (hypertext transfer protocol — протокол передачи гипертекста), FTP (file transfer protocol — протокол передачи файлов), доступ к локальным файлам или протоколы баз данных на ос- нове соединения. Динамический HTML не накладывает никаких ограни- чений на передачу данных. Большинство грамотно разработанных объектов источников данных будут поддерживать асинхронную передачу данных — то сеть, объект источни- ка данных будет выводить данные постепенно, по мере передачи их кли- енту вместо ожидания всего набора данных и последующего его вывода на экран. Поскольку браузер Microsoft Internet Explorer 4.0 поддерживает постепенный вывод связанных данных, то использование объекта источ- ника данных, который поддерживает асинхронную передачу, приведет к более быстрому отображению доступных для взаимодействия с пользова- телем данных, аналогично постепенному выводу на экран изображения в формате GIF. □ Установка механизмов для определения передаваемых данных. Поскольку объекты источников данных отвечают за передачу данных, то они также ответственны за механизм, который определяет передаваемые (запраши- ваемые) данные. Объекты источников данных могут свободно использо- вать язык запросов по своему выбору, URL, пути к файлам, другие про- цессы, другие объекты и другие средства определения совместимости данных с протоколом, который они используют для доступа к данным. □ Обеспечение методов доступа к данным на клиентской машине. Объекты источника данных могут поддерживать свойства и методы манипулиро- вания данными, которые они поставляют. Например, объекты источника данных, включенные в состав Internet Explorer 4.0, поддерживают свойст- ва и методы сортировки и отбора данных, которые они поставляют. Ко- гда вы устанавливаете данные свойства или вызываете данные методы из сценария, то объект источника данных выполняет манипулирование и, посредством передачи уведомлений агенту связывания и повторения, со-
434 Часть IV. Содержание документа и связывание данных обтает браузеру, что данные были изменены. Браузер в свою очередь об- новляет связанные данные для отражения текущего порядка (для сорти- ровки) или нового, сокращенного или расширенного набора данных (для отбора). Объекты источников данных могут также поддерживать обновление дан- ных. Объект источника данных может предоставить пользователю возмож- ность изменения значений связанных HTML-элементов на Web-странице. Объект источника данных передает измененные данные обратно источнику данных, обычно базе данных или Web-серверу, где изменения будут сохра- нены. RDS (Remote Data Service — удаленная служба данных) является од- ним из таких объектов источника данных. RDS включена в минимальной конфигурации в Internet Explorer 4.0. Более подробную информацию о RDS можно найти на Web-узле компании Microsoft по адресу www.microsoft.com/data. Сортировка, отбор и обновление не являются единственными манипуля- циями, которые поддерживаются объектами источников данных. Объект источника данных может поддерживать любые манипуляции, соответст- вующие типу поставляемых данных. Например, объект источника дан- ных, который содержит расписание выплат процентов за кредит, может представлять три свойства: процентную ставку, объем ссуды и срок вы- платы. При изменении любого из данных свойств объект источника дан- , ных будет генерировать отличный набор данных, поскольку изменения значений изменят график выплаты процентов за ссуду. □ Обеспечение объектной модели для доступа к данным с помощью сценария (объектная модель данных). В общем, связывание данных не требует или требует минимального сценария для построения базовых страниц, если только вам не требуется выполнять проверку, расчеты или манипуляции данными. Браузер Internet Explorer 4.0 обеспечивает объектную модель ADO для каждого объекта источника данных. Однако объекты источника данных могут представлять свою собственную дополнительную объектную модель в условиях, когда к данным нельзя обращаться, используя ADO. Приме- ром объекта источника данных является объект источника данных XML (extensible Markup Language — расширяемый язык разметки). На Web- узле компании Microsoft (по адресу www.microsoft.com/standards/xml) можно найти дополнительную информацию по данному вопросу. HTML-расширения связывания данных Данные из источника данных отображаются на экране пользователя с по- мощью стандартных HTML-элементов. Ключом *к данным элементам, ото- бражающим данные, является добавление одного или более HTML- расширений связывания данных.
Глава 15. Связывание данных с помощью HTML' 435 ( Примечание j Расширения связывания данных были предложены консорциуму W3C (World Wide Web Consortium) для включения в стандарт HTML. Расширения связывания данных представляют собой четыре атрибута, кото- рые могут быть добавлены к множеству элементов HTML. Атрибуты опреде- ляют объект Источника данных, который поставляет данные в элемент, определяет связывание с определенным столбцом или полем объекта источ- ника данных, определяет представление данных в виде обычного текста или в виде HTML, а также определяет, будет ли таблица с повторением отобра- жать только подмножество данных, поставляемых объектом источника данных. В следующих разделах данные атрибуты обсуждаются подробно. Полный список эле- ментов, которые поддерживают атрибуты связывания данных, можно найти ниже в разделе данной главы "Потребители данных: элементы HTML ". Простой провайдер OLE-DB В общем случае, объект источника данных считывает данные в кэш в памя- ти клиентского компьютера. Объект источника данных должен затем иметь возможность представить эти данные браузеру. Объекты источника данных осуществляют эту задачу путем реализации интерфейса OSP (OLE-DB Sim- ple Provider — простой провайдер OLE-DB) или прямо через OLE-DB, кото- рый является набором интерфейсов OLE для доступа к данным. Браузер Internet Explorer 4.0 поддерживает все объекты источников данных, реализующих OSP. RDS, включенный в состав Internet Explorer 4.0, является единственным поддерживаемым провайдером OLE-DB для Internet Explorer 4.0. Поддержка произвольных провайдеров OLE-DB будет добавлена в бу- дущих версиях, но в данном разделе рассматривается только OSP. OSP является открытой спецификацией и совместим с JavaBeans (моделью компонентов для Java) и OLE. OSP предоставляет простой интерфейс для вывода данных из клиентского кэша. В большинстве случаев кэш клиент- ской стороны можно просматривать как массив или набор табличных дан- ных, то есть набор данных, состоящий из строк, в котором каждая строка имеет одинаковое число столбцов. OSP предоставляет доступ по очереди к каждой ячейке этого массива данных. OSP поддерживает способность до- бавления и удаления строк. OSP также требует, чтобы объект источника данных генерировал уведомления при измененйи ячеек или при добавлении или удалении строк. Данные уведомления используются агентом связывания и повторения браузера Internet Explorer 4.0 для поддержания в синхронизи- рованном состоянии каждого связанного элемента со значениями данных текущей записи. Объекты источника данных, которые представляют OSP, могут быть реализованы на языках программирования Java, Microsoft
436 Часть IV. Содержание документа и связывание данных Visual Basic 5.0 и Microsoft Visual C++, при помощи MFC (Microsoft Founda- tion Classes) или, что более предпочтительно, ATL (Application Transaction Language) 2.0. Атрибут DATASRC Атрибут datasrc указывает объект источника данных, который поставляет данные. DATASRC установлен равным #<ldref>, где <iDref> является иден- тификатором объекта источника данных. Используя пример, приведенный в разделе "Объекты' источников данный', атрибут datasrc, указывающий на объект stocklist, можно представить следующим образом: DATASRC-#stocklist В общем, атрибут datasrc не используется самостоятельно, а только в соче- тании с атрибутом datafld. Однако имеется одно исключение из этого пра- вила: таблицы с повторением. Таблицы с повторением используют только атрибут datasrc, поскольку связывание таблицы с повторением указывает только источник повторения. Связанные HTML-элементы внутри таблицы отображают и взаимодействуют с реальными данными. Атрибут DATAFLD Объекты источников данных представляют свои данные в табличной форме в виде множества строк с фиксированным количеством столбцов. Объект источника данных устанавливает имена столбцов, на которые можно ссы- латься посредством интерфейса OSP. Определение имени столбца является обязанностью объекта источника данных. Атрибут datafld указывает имено- ванный столбец или поле, которое должно быть связано с объектом источ- ника данных. В общем случае вместе с атрибутом datafld должен быть указан атрибут datasrc. Однако для элемента внутри таблицы с повторением атрибут datasrc опускается, поскольку он наследован из атрибута datasrc элемента Table. Ниже в разделе данной главы "Связывание таблицы с повторением" приведена более подробная информация по этому вопросу. Атрибут DATAFORMATAS Атрибут dataformatas определяет формат данных, поставляемых объектом источника данных, dataformatas может принимать одно из трех значений: none, text или html. По умолчанию устанавливается значение none. Если установлено значение none (или когда данный атрибут отсутствует), то в объекте источника данных запрашивается исходный тип, необходимый для потребителя данных, который почти всегда является текстом для элементов
Гпава 15. Связывание данных с помощью HTML 437 html. Если установлено значение text, то у объекта источника данных за- прашивается текстовое значение, независимо от основного типа данных столбца. Например, если объект источника типа данных поставляет столбец с целочисленными значениями, то потребуется преобразовать эти значения в строки, если значение атрибута dataformatas было равно text. Наиболее важно, что когда атрибут dataformatas имеет значение html, то данные, поставляемые объектом источника данных, интерпретируются как код HTML, а не как простой текст. Данные анализируются и все элементы HTML в них интерпретируются так, как будто они были представлены не- посредственно на Web-странице. Путем установки значения атрибута dataformatas равным html можно сохранить код HTML вместе с данными, а не хранить код статически на странице. Атрибут DATAPAGESIZE Атрибут datapagesize используется для таблицы с повторением и дает Web- мастеру возможность ограничить длину таблицы с повторением и, таким образом, общую длину страницы со связанными данными. Атрибут может быть положительным целым числом и используется в сочетании с атрибу- том DATASRC. Если атрибут datapagesize не указан, то шаблон таблицы повторяется объектом источника записей для каждой записи. Добавление атрибута dataformatas в таблицу позволяет установить число повторений шаблона равным определенной величине. Строки, отображаемые в таблице, могут быть затем прокручены с помощью методов объектной модели динамиче- ского HTML-элемента Table. Агент связывания и повторения Третьим компонентом архитектуры связывания данных является агент свя- зывания и повторения (binding and repetition agent), который для краткости называется агентом связывания. Агент связывания является внутренним компонентом браузера Internet Explorer 4.0 и отвечает за интерпретацию ат- рибутов связывания данных и последующую передачу данных из объекта источника данных потребителям данных. Для реализации этой функции агент связывания выполняет ряд задач. Сначала агент связывания распозна- ет объекты источников данных и потребителей данных, находящихся на странице или добавляемых динамически на страницу с помощью объектной модели динамического HTML. Агент связывания отслеживает, какие объек- ты источников данных доступны и с какими столбцами объекта источника данных связаны потребители данных. Агент связывания также выполняет обработку в соответствии с установлен- ным типом связывания. Для связывания текущей записи агент связывания
438 Часть IV. Содержание документа и связывание данных поставляет данные из текущей записи потребителям данных. Когда новая запись становится текущей, то агент связывания поставляет потребителям данных информацию из новой текущей записи. При связывании таблицы с повторением агент связывания повторяет шаблон таблицы для каждой запи- си, поставляемой объектом источника данных. Индивидуальные связанные элементы внутри таблицы являются значениями, поставляемыми из соответ- ствующего столбца для каждой записи в объекте источника записей. Второй функцией агента связывания является поддержание данных потре- бителей данных и объектов источников данных в синхронизированном со- стоянии. В действительности при этом выполняются две задачи. Агент свя- зывания отслеживает объекты источников данных и обнаруживает измене- ния данных путем обработки уведомлений. Когда данные, с которыми связан HTML-элемент, изменяются, то агент связывания распространяет изменения на связанный элемент. Аналогичным образом, когда пользова- тель изменяет значение связанного элемента при взаимодействии с табли- цей, то агент связывания передает изменение обратно объекту источника данных. Наконец, агент связывания отвечает за запуск событий сценариев для объ- ектов источников данных и потребителей данных. События предоставляются потребителями данных, что позволяет Web-мастерам писать сценарии, кото- рые проверяют вводимые пользователем данные или отвечают па предпри- нимаемые пользователем действия, такие как установка новой текущей записи. Более подробную информацию о доступных событиях сценариев можно найти ниже в разделе данной главы "Написание сценариев с использо- ванием связывания данных?’. Потребители данных: HTML-элементы При связывании данных используются стандартные HTML-элементы, включающие HTML-элементы Form, базовые HTML-конструкции, такие как Anchor и image, более эзотерические конструкции типа object и Applet, простые контейнеры для других HTML-элементов, таких как div и Span, и элементы Table для повторения элементов из набора данных. В данном раз- деле представлено подробное объяснение каждого потребителя данных, на- чиная с базовых потребителей и заканчивая более сложными элементами. Элементы DIV и Span Элементы div и Span представляют собой простые контейнеры для тексто- вых элементов и других HTML-элементов. Поскольку div и Span являются блочными элементами (они имеют открывающий и закрывающий теги), то связывание этих элементов состоит в связывании содержания. Оба элемента
Глава 15. Связывание данных с помощью HTML 439 поддерживают атрибут dataformatas и могут быть связаны с данными HTML в столбце объекта источника данных. Содержание элементов не мо- жет быть изменено в средстве просмотра страницы. Поэтому связывания с элементами div и Span доступны только для чтения. ( Примечание Данные могут быть, тем не менее, изменены посредством объектной модели данных. В этом случае изменения данных из сценария будут отражены в свя- занных элементах Div и Span. <DIV DATASRC=#stocklist DATAFLD="Symbol" DATAFORMATAS=TEXTX/DIV> <SPAN DATASRC=ff stocklist DATAFLD="ChangeF" DATAFORMATAS=HTMLx/SPAN> Элемент Input Ниже перечислены типы элемента input, которые поддерживают связыва- ние данных: □ type=text — Связывание данных активизирует связывание с атрибутом value текстового окна и при поддержке нормального режима операций текстового окна позволяет пользователю редактировать значение. Изме- нения элемента сохраняются в объекте источника данных. Пример свя- зывания текстового окна: <INPUT TYPE=TEXT DATASRC=#stocklist DATAFLD="Shares"> □ type=radio — Связывание данных связывает атрибут value с группой кнопок-переключателей, имеющих одинаковое значение атрибута name. Атрибуты datasrc и datafld должны быть добавлены во все кнопки- переключатели в группе. Если связанное значение из источника данных не совпадает со значениями связанных кнопок-переключателей, то кноп- ка-переключатель не будет выбрана. Когда пользователь выбирает кноп- ку-переключатель, то соответствующее значение сохраняется в объекте источника данных. Пример группы кнопок-переключателей со связанными данными приве- ден ниже: <INPUT TYPE=RADIO VALUE’S DATASRC=#Stocklist DATAFLD=”Type">Short <INPUT TYPE’RADIO VALUE’L DATASRC=#stocklist DATAFLD="Type">Long □ type=checkbox — Модель поведения связывания данных флажка сущест- венно отличается от его модели поведения в HTML-форме. Флажки со связанными данными связывают логическое значение, а не атрибут value
440 Часть IV. Содержание документа и связывание данных флажка. Флажок со связанными данными принимает значение True или False. Пример флажка со связанными данными показан ниже: CINPUT TYPECHECKBOX DATASRC=#stocklist DATAFLD="ExDiv"> □ type=hidden — Скрытый элемент связывания данных полезен только в комбинированных страницах, которые используют связывание данных в сочетании с кнопкой Submit (Отправить). Атрибут value скрытого эле- мента связывания данных является связанным. При отправке HTML- формы, которая содержит скрытый элемент связывания данных, значе- ние скрытого элемента будет отправлено на сервер. Пример скрытого элемента со связанными данными показан ниже: CINPUT TYPE=HIDDEN DATASRC=#stocklist DATAFLD="DateUpdated"> □ type=password - Поля пароля co связанными данными имеют точно та- кую же модель поведения, как и текстовые окна со связанными данны- ми. Их атрибут value связан, и значение, вводимое пользователем, со- храняется в объекте источника данных. ( Примечание ) Элементы input не требуют включения элемента Form, когда используется связывание данных. Также не требуется кнопка Submit (Отправить). Элемент TextArea Связывание данных элемента TextArea связывает весь текст, находящийся в текстовом окне со множеством строк, с одним столбцом. Пример элемента TextArea со связыванием данных показан ниже: CTEXTAREA DATASRC=#stocklist DATAFLD="News"> Элемент Marquee Как и для элементов div и span, связывание с элементом Marquee обеспечи- вает связывание с содержанием элемента. Вы можете при желании добавить атрибут dataformatas=html для указания, что связанными данными является код HTML. После этого данные будут проанализированы и воспроизведены браузером. Пример элемента Marquee со связыванием данных показан ниже: <MARQUEE DATASRC=#stOCklist DATAFLD="Last" DATAFORMATAS=HTML> </MARQUEE>
Гпава 15. Связывание данных с помощью HTML 441 Элемент Select Элемент select со связыванием данных позволяет связывать одиночный выбранный элемент из списка. Атрибут value выбранного элемента Option представляет собой значение, сохраняемое в связанном столбце объекта источника данных. Когда значение в объекте источника данных не соответ- ствует значениям, определенным элементом option в элементе Select, то значения не выделяются. Элементы Select со связыванием данных могут использовать раскрывающийся список или раскрывающееся поле со спи- ском для взаимодействия с пользователем в зависимости от установки атри- бута size. Атрибут multiple игнорируется в элементах Select со связывани- ем данных, поскольку невозможно связать элемент более чем с одним зна- чением из одного столбца. Пример раскрывающегося поля со списком со связыванием данных приве- ден ниже: CSELECT DATASRC=#stocklist DATAFLD="Type"> COPTION VALUE=L>Long COPTION VALUE=S>Short C/SELECT> Раскрывающийся список co связыванием данных использует приведенный ниже элемент Select: CSELECT SIZE=2 DATASRC=#stOcklist DATAFLD="Type"> COPTION VALUE=L>Long COPTION VALUE=S>Short • C/SELECT> Хотя список вариантов для элемента Select не может быть связан непо- средственно с объектом источника данных, но это возможно с помощью сценария, для заполнения вариантов элемента select из объекта источника данных. Приведенный ниже код иллюстрирует данный метод: с!— Объект источника данных поставляет варианты для элемента Select —> cOBJECT ID=”selectlist" WIDTH="0” HEIGHT="0" CLASSID="clsid:333C7BC4-460F-llD0-BC04-0080C7055A83"> CPARAM NAME="DataURL" VALUE="selectdata.txt”> CPARAM NAME="UseHeader" VALUE="True”> C/OBJECT> c!— Заполняемый список —> CSELECT ID=typeselect> c/SELECT> CSCRIPT FOR=window EVENT=onload() LANGUAGE»"JavaScript"> var i, newop;
442 Часть IV. Содержание документа и связывание данных selectlist.recordset.MoveFirst(); for (i = 1; i <= selectlist.recordset.AbsolutePosition; i++) ( newop = document.createElement("option"); newop.value = selectlist.recordset("value"); newop.text = selectlist.recordset("display"); typeselect.add(newop); selectlist.recordset.MoveNext(); ) </SCRIPT> Обработчик события onload окна читает данные из объекта источника дан- ных и добавляет вариант для каждой записи в данных в элемент Select. Ме- тод MoveFirst и свойство AbsolutePosition обсуждаются ниже в разделах данной главы "Методы Move" и "Свойство recordNumber". Элемент IMG Связывание данных поддерживает связывание атрибута src элемента img. Значение, поставляемое связыванием, должно быть адресом URL файла отображаемого изображения. Адрес URL может быть абсолютным или отно- сительным. Когда используется относительный URL, то для создания пол- ного URL с целью извлечения файла изображения используется базовый URL документа или URL, указанный в теге <base>. Загрузка файла изобра- жения выполняется так, как будто элемент img был статически определен внутри документа, то есть данные изображения загружаются в нитях, дос- тупных для браузера. Пример элемента img со связыванием данных: <IMG DATASRC=#stocklist DATAFLD="Chart"> Элемент Anchor В динамическом HTML поддерживается связывание с атрибутом href эле- мента Anchor по аналогии с элементом img. Подразумевается, что связанное значение является относительным или абсолютным URL. К элементу Anchor применимы те же правила, которые применяются к элементу img. Пример элемента Anchor со связыванием данных: <А DATASRC=#stocklist DATAFLD="Website">...</А> Вы можете включить связанный текст в элемент Anchor, используя якорь в комбинации с другими элементами, такими как элемент Span. В приведен- ном ниже примере в качестве гиперссылки на Wcb-узел компании исполь- зуется сокращенное название акции (symbol): <А DATASRCMstocklist DATAFLD="Website">
Глава 15. Связывание данных с помощью HTML 443 <SPAN DATASRC=#stocklist DATAFLD="Synibol"></SPAN> </A> Элемент Button Можно связать содержание элемента Button путем включения атрибутов datasrc и datafld элемента. На поверхности кнопки будет отображен свя- занный с ней текст. Атрибут dataformatas может быть также использован при связывании для отображения HTML на поверхности кнопки. Пример элемента Button со связыванием данных: <BUTTON DATASRC=#stOcklist DATAFLD="Chart" DATAFORMATAS=HTMLX/BUTTON> Элемент Label Связывание элемента Label аналогично связыванию элемента Button. Со- держание элемента Label является связанным, и связывание может содер- жать код HTML. Но следует иметь в виду, что элементы Label не могут быть использованы внутри таблицы с повторением. Поскольку элемент Label связан с элементом управления путем установки значения его атрибу- та for равным идентификатору связанного элемента управления, то невоз- можно уникальным образом назначить элемент Label одиночному элементу управления в таблице с повторением. Элементы Object и Applet Вы можете также связать произвольное число свойств элементов управления ActiveX и апплетов Java. Для связывания свойства элемента object или Applet необходимо включить атрибуты datasrc и datafld в тег <param>, который определяет имя связываемого свойства. Следующий пример показывает связи с цветом текста и фона для элемента управления или апплета: <APPLET CODE=myapplet.class> <PARAM NAME=”backcolor” VALUE="green" ' DATASRC="#dsc1" DATAFLD="color"> <PARAM NAME=”forecolor" VALUE="yellow” DATASRC="#dscl" DATAFLD=”textcolor”> </APPLET> Для связывания апплетов Java элемент Applet должен быть реализован в со- ответствии со спецификациями JavaBcans для свойств, то есть должны быть соответствующие общие методы get и set для свойства, определенного ат-
444 Часть IV. Содержание документа и связывание данных рибутом name тега <param>. Как и для элементов ActiveX, не требуется, чтобы элемент Applet генерировал уведомления изменения свойств. Элементы объекта (элементы управления ActiveX) работают точно так же, как и элементы Applet. Пример элемента object со связыванием данных показан ниже: <OBJECT CLSID=". . . "> <PARAM NAME=”backcolor" VALUE-"blue" DATASRC="#dscl" DATAFLD="color"> <PARAM NAME»"forecolor" VALUE="white" DATASRC="#dscl" DATAFLD="textcolor”> </OBJECT> Элемент управления ActiveX должен поддерживать свойство, имя которого определено атрибутом name тега <param>. Большинство элементов управле- ния ActiveX генерируют уведомления, когда значение свойства изменяется. Однако связывание данных этого не требует. Элементы управления ActiveX могут определять свойство по умолчанию для связывания путем установки флага DefaultBind во вводимой информации для свойства. Связывание данных поддерживает связывание с данным свой- ством по умолчанию путем установки атрибутов datasrc и datafld непо- средственно для элемента object: OBJECT CLSID="...“ DATASRC="#dscl" DATAFLD»”text"> <PARAM NAME="backcolor" VALUE="blue" DATASRC»"#dscl" DATAFLD="color"> <PARAM NAME="forecolor" VALUE="white" DATASRC»"# ds с1" DATAFLD»"textcolo r"> </OBJECT> Обратите внимание, что вы можете совместить связывание по умолчанию с любым числом связей с элементом Param. Элементы Frame и IFrame Вы можете связать атрибуты href элементов Frame и iFrame. В обоих случа- ях связанные данные должны содержать URL. Различия обусловлены тем, что элементы iFrame могут существовать на любой странице. Элемент iFrame может быть использован подобно другим элементам, которые поддерживают связывание данных, путем добавления атрибутов datasrc и datafld:
Глава 15. Связывание данных с помощью HTML 445 <IFRAME DATASRC=#stocklist DATAFLD="Website"> С другой стороны, элемент iFrame должен существовать внутри элемента Frameset, а не внутри тела HTML-документа. Для использования преиму- ществ связывания Frame объект источника данных должен быть размещен внутри элемента Head HTML-документа, который содержит элемент Frameset: <HTML> <HEAD> <OBJECT ID="stocklist” WIDTH="0" HEIGHT=”0" CLASSID="clsid:333C7BC4-460F-llD0-BC04-0080C7055A83"> <PARAM NAME="DataURL" VALUE="stockdata.txt"> <PARAM NAME="FieldDelim" VALUE="|"> <PARAM NAME="TextQualifier" VALUE=""> <PARAM NAME="UseHeader" VALUE="true"> </OBJECT> </HEAD> <FRAMESET> <FRAME DATASRC=#stocklist DATAFLD="Website"> </FRAMESET> </HTML> Связывание с элементом Frame полезно, когда требуется предоставить поль- зователю возможность просмотра последовательности списка URL. Связы- вание текущей записи используется с элементом Frame, и при удалении те- кущей записи элемент Frame отображает данные из нового URL, поставляе- мого объектом источника данных. Элементы Frame не могут быть использованы внутри таблицы с повторением. Элемент Table Последним поддерживаемым потребителем данных является элемент Table. Элемент Table является специальным потребителем данных — он является контейнером для остальных связей, не устанавливая связывание непосред- ственно с данным элементом. Связывание элемента Table определяет, что содержание таблицы, исключая элементы тнеаб и TFoot, повторяется в на- боре данных, определяемых атрибутом datasrc: <TABLE DATASRC=#stocklist> </TABLE> Когда содержание таблицы повторяется, то связанный элемент внутри эле- мента Table принимает его данные из текущей записи и из последующих за- писей в источнике записей. В приведенном ниже примере таблица отображает
446 Часть IV. Содержание документа и связывание данных список всех условных обозначений акций с указанием последней котировки, изменения и объема продаж из источника данных с именем stocklist: CTABLE ID="stocktbl" DATASRC="#Stocklist" BORDER=1> <THEAD> <TR ONCLICK="sort() ; "> <TD CLASS=thdXDIV ID=Symbol>Symbol</DTVX/TD> <TD CLASS=thdXDIV ID=Last>Last</DIVX/TD> <TD CLASS=thdXDIV ID=Change>Change</DIVx/TD> <TD CLASS-thdxDIV ID=Volume>Volume</DIVX/TD> </TR> </THEAD> <TBODY> <TR> <TDXA DATAFLD="Website”> <SPAN DATAFLD="Synibol"X/SPANX/A> </TD> <TD ALIGN=right> <DIV DATAFLD="Last"X/DIV> </TD> <TD ALIGN=right> <SPAN DATAFLD="ChangeF" DATAFORMATAS=HTMLX/SPAN> </TD> <TD ALIGN-rightXDIV DATAFLD="Volume,,x/DIV></TD> </TR> </TBODY> </TABLE> В Repealed Table Data Binding Microsoft Inlet net Expl... Hlwl pl Repeated Table SYmhol Last [Change Volume i| jaapl i 19 19] i . 691 4302800] iamzn :| 29.Г 0-25 [ 299000] |csco J| 79.811 0.251 5469200! ..J10477g|'"'"’JLOO Г 4000800 [ T 9381' [218467001 :|msft [14бГбЗ[ -0.75 Г 73641 obi |ns^'ZjE3?-63T.....Ь 94 [ 1768800 i !огсГ"""’Т’54.88'Г бйй| 43454001 (sunw [45.061 ~ -0.63[ 5014000] |yhoo~Z[Z5-25[ -L25j 829600] На рис. 15.1 показана получен- ная в результате таблица. Рис. 15.1. Пример таблицы с повторением
Глава /5. Связывание данных с помощью HTML 447 В табл. 15.1 перечислены потребители данных, атрибуты связывания дан- ных, которые они поддерживают, и указана возможность поддержки обнов- ления данных. Таблица 15.1. Список потребителей данных Тег Связанный атрибут й ITAFLD kTAFORMATAS ы ы со § § Обновление данных Q Q Q Q CDIV> Содержание X X X cSPAN> Содержание X X X CINPUT TYPE=TEXT> VALUE X X X CINPUT TYPE=RADIO> VALUE X X X CINPUT TYPE=CHECKBOX> Логический, соответ- ствующий проверяе- мому состоянию X X X CINPUT TYPE=HIDDEN> VALUE X X CINPUT TYPE=PASSWORD> VALUE X X X CTEXTAREA> Содержание X X X CMARQUEE> Содержание X X X cSELECT> Выбранный элемент X X X CIMG> SRC X X г <A> HREF X X CBUTTON> Содержание X X X • cLABEL> Содержание X X X cOBJECT> или CAPPLET> Свойство по умолчанию X X X CPARAM> Свойство объекта X X X или апплета cFRAME> HREF X X cIFRAME> HREF X X CTABLE> Повторение X X
448 Часть IV. Содержание документа и связывание данных Обратите внимание, что в примере для элемента Table элементы со связы- ванием данных внутри элемента Table не определяют атрибут datasrc. По- скольку элемент т?йе повторяется, то элементы в таблице наследуют зна- чение атрибута datasrc (а именно, «stocklist) из таблицы с повторением. Вы можете включить несколько элементов твобу и строк с любым количе- ством атрибутов rowspan и colspan. При создании таблицы с повторением следует создать таблицу для отображения и форматирования данных оди- ночной записи из объекта источника записей. Все содержание таблицы бу- дет затем повторяться для каждой записи в наборе данных. Можно ограни- чить число записей, повторяемых в элементе Table. Ниже « разделе данной главы "Таблицы с разбиением" приведена более подробная инфор- мация по этому вопросу. Построение базовых страниц с помощью связывания данных Теперь, когда вы понимаете роль объектов источников данных, атрибутов, используемых для определения связывания и HTML-элементов, которые могут быть связаны, используем полученные знания для построения трех базовых страниц. Связывание текущей записи Вы можете представить текущую запись, как индекс или указатель на неко- торую запись в источнике данных. Значения из столбцов в данной записи отображаются в связанных элементах. В качестве текущей можно установить любую запись путем увеличения или уменьшения индекса или указателя. Когда новая запись становится текущей, связанные элементы динамически изменяются для отражения данных из новой записи. Приведенный ниже код демонстрирует определение связывания текущей записи: <BODY TOPMARGIN=0 LEFTMARGIN=40 BGCOLOR="#FFFFFF"> <FONT FACE="verdana,arial,helvetica" SIZE=2> <H2>Current Record Binding</H2> <P>Stock: <A DATASRC=lr stocklist DATAFLD=,'Website"> <SPAN DATASRC=#stocklist DATAFLD="CofhpanyName"X/SPAN> &nbsp;(<SPAN DATASRC=#stocklist DATAFLD=” Symbol "X/SPAN>) </A>
Гпава 15. Связывание данных с помощью HTML 449 cP>Last: CSPAN DATASRC=#stocklist DATAFLD="Last”>C/SPAN> cp>Change: <SPAN DATASRC=#stocklist DATAFLD=”ChangeF" DATAFORMATAS=HTML> c/SPAN> <P>Chart: <IMG ALIGN=top DATASRC=#stocklist DATAFLD="Chart”> <HR> CINPUT TYPE=BUTTON VALUE=" |< " ONCLICK=’’stocklist. recordset.MoveFirst () ;"> &nbsp; CINPUT TYPE=BUTTON VALUE=" < " ONCLICK="stocklist.recordset.MovePrevious();"> &nbsp; CINPUT TYPE=BUTTON VALUE=" > ’’ ONCLICK="stocklist.recordset.MoveNext ();"> inbsp; CINPUT TYPE=BUTTON VALUE=" >I " ONCLICK="stocklist.recordset.MoveLast{);”> c/BODY> Для связывания текущей записи каждый связанный элемент содержит атри- буты DATASRC И DATAFLD. На рис. 15.2 показан пример связывания текущей записи. Рис. 15.2. Страница, использующая связыва- ние текущей записи
450 Часть IV. Содержание документа и связывание данных Обратите внимание, что в данном примере добавлены четыре кнопки HTML. Эти элементы управления дают возможность пользователю устанавливать текущую запись в источнике данных. Нажатие кнопок выводит на экран первую, предыдущую, следующую или последнюю запись в качестве теку- щей записи. Данный метод подробно обсуждается ниже в разделе данной главы "Методы перемещения". Связывание таблицы с повторением Приведенный ниже код демонстрирует создание простой таблицы с повто- рением. Пример построен на основе рассмотренной ранее таблицы акций с некоторыми изменениями. Здесь столбец Symbol содержит условное обозна- чение акции и связанный элемент Anchor, который указывает на Web-узел соответствующей компании. Данные были помешены в две строки таблицы и добавлен небольшой график для каждого элемента таблицы с целью де- монстрации динамики изменения стоимости акций за последние шесть ме- сяцев. Ячейка, содержащая диаграмму, охватывает две строки каждого эле- мента. <TABLE ID="stocktbl" DATASRC="#stocklist" BORDER=1> <THEAD> <TR ONCLICK="sort();"> <TD CLASS=thd ROWSPAN=2><DIV ID=Symbol>Symbol</RIVx/TD> <TD CLASS=thdXDIV ID=Last>Last</DIVX/TD> <TD CLASS=thdXDIV ID=Change>Change</DIVX/TD> <TD ROWSPAN=2>Chart</TD> </TR> <TR ONCLICK="sort() ; "> <TD CLASS=thdXDIV ID=Volume>Volume</DIVX/TD> <TD CLASS=thdXDIV ID=Type>Type</DIVX/TD> </TR> </THEAD> <TBODY> XTR> <TD ALIGN=left ROWSPAN=2> <A DATAFLD="Website"XSPAN DATAFLD=',Symbol’’X/SPANX/A> </TD> <TD ALIGN=right> <DIV DATAFLD="Last"x/DIV> </TD> <TD ALIGN=right> <SPAN DATAFLD=”ChangeF" DATAFORWWAS=HTMLx/SPAN> </TD> <TD ALIGN=left ROWSPAN=2>
Глава 15. Связывание данных с помощью HTML 451 <IMG DATAFLD="Chart"> </TD> </TR> <TR> <TD ALIGN=right> <DIV DATAFLD="Volume"x/DIV> </TD> <TD ALIGN=center> <SELECT DATAFLD="Type"> COPTION VALUE=L>Long cOPTION VALUE=S>Short </SELECT> </TD> </TR> </TBODY> </TABLE> Некоторые рассмотренные здесь концепции могут быть не совсем очевид- ны. Во-первых, вы можете использовать многочисленные связывания в од- ной ячейке таблицы. Первая ячейка содержит элементы Anchor и Span, каж- дый из которых связан с различными полями. Помните, что элемент Table является просто контейнером для повторения. Спецификация шаблона мо- жет включать в себя любой элемент или элемент управления, содержащий или не содержащий связывание данных, а также шаблон в соответствии с правилами HTML. На рис. 15.3 показана измененная таблица с параметрами акций. Обратите внимание, что в данном примере используется TDC (Tabular Data Control — элемент управления табличными данными) в качестве источника данных. TDC является объектом источника данных, включенным в мини- мальной конфигурации в браузер Internet Explorer 4.0. Данный элемент ис- пользуется для извлечения данных в разделенном текстовом формате. Набор данных, использованный в примерах этого раздела, имеет поля, перечис- ленные в табл. 15.2. Таблица 15.2. Типы полей набора данных Поле Тип данных Поле Тип данных Symbol text %Change float Last float DateUpdated text Change float High float ChangeF text Low float Volume int Open float
452 Часть IV. Содержание документа и связывание данных Таблица 15.2 (окончание) Поле Тип данных Поле Тип данных Close float Shares int 52WeekHigh float Website text 52WeekLow float Chart text PERatio float Type text CompanyName text ExDiv text IQ Repeated Table Data Binding - Microsoft Internet Explorer -laixlf J» File Edit yist?; ijo Favorite: Help i g> Repeated Table Symbol Volume 19.19! aapi. 4302800' | Short! "/Г 29 amzn 29900011 Short Д 79.81! csco Ibm 5469200=51 Long Ml 104.75 -1.00 4000800 ! I Long 1.69 0.25 0.25 HHIIM.IIIM) IA*»I ЙШЕИ! КЗЯЕЗК .. Jb-,.; ; вЗЯЯЕЯВ ЮТГЗЯ Chart ННЙВШ __№H 5ИИПП ЖВЕЕЗ ЯБЕЯЕОЯГ . Jim* JTT-W г-ме-г г* • X • ---‘♦в ртта|йг м> Co^pute( ИНЯИ Рис. 15.3. Базовое связывание таблицы с повторением
Глава 15. Связывание данных с помощью HTML 453 Связывание таблицы с разбиением В приведенном выше примере таблица повторялась для каждой записи в на- боре данных. Это может привести к образованию больших таблиц, которые будет трудно просматривать и выводить на экран. Для решения этой пробле- мы была предложена концепция разбиения таблицы (table paging). Разбиение таблицы позволяет Web-мастеру определять точное число записей, которые будут отображены в таблице с повторением в определенное время. Данный метод позволяет Web-мастеру ограничивать размер страницы, полученной в результате повторения шаблона таблицы. Метод также позволяет Web-мастеру ограничивать таблицу определенной областью на странице и помешать другие элементы на странице вокруг таблицы, не заботясь о том, что элементы, рас- положенные ниже таблицы, не будут отображаться на экране. Для запуска разбиения таблицы атрибут datapagesize определен в таблице с повторением. Атрибут datapagesize принимает целочисленный аргумент, который определяет число записей из набора записей и число экземпляров шаблона таблицы, которые должны быть повторены в таблице единовре- менно. (Отображение частичных шаблонов не поддерживается). Для активизации разбиения таблицы можно использовать код предыдущего примера, в котором требуется произвести только одно изменение в атрибуте datapagesize элемента Table, которое показано ниже: <TABLE ID="stocktbl" DATASRC="#stOCklist" DATAPAGESIZE=4 BORDER=1> </TABLE> Данный код одновременно отображает в таблице данные из четырех записей. На рис. 15.4 показан пример таблицы с данными акций с активизирован- ным разбиением таблицы. Но как пользователю теперь просмотреть остальные табличные данные? В таб- лицах с повторением и разбиением представлены два метода для просмотра до- полнительных данных из набора данных: nextpage, который отображает сле- дующую страницу данных в таблице, и previousPage, который отображает пре- дыдущую страницу данных. Используя данные методы, Web-мастер может добавить HTML-элементы, которые вызывают сценарии для отображения до- полнительных страниц данных. Кнопки Next (Следующая) и Previous (Предыду- щая), показанные на рис. 15.4, вызывают методы nextPage и previousPage В таблице с повторением. Данные кнопки определены следующим образом: <INPUT TYPE-BUTTON VALUE=” Previous " ONCLICK=”stocktbl.previousPage();"> <INPUT TYPE=BUTTON VALUE-" Next " ONCLICK=”stocktbl.nextPage() ; ”>
454 Часть IV. Содержание документа и связывание данных Рис. 15.4. Базовое связывание разделенной таблицы Стоит также рассмотреть граничные условия. Если вызывается метод nextPage, когда в наборе осталось меньше страницы данных, то таблица ото- бражает только оставшиеся записи. После чего метод nextPage отключается. Если метод previousPage вызывается, когда текущую запись от первой стра- ницы отделяет менее одной страницы, то отображается вся страница запи- сей, начиная с первой записи. Затем метод previousPage отключается. Нако-
Глава 15. Связывание данных с помощью HTML 455 нец, когда записи динамически добавляются и удаляются, то отображаемые данные будут настраиваться соответствующим образом. В этом случае за- пись, отображаемая в верхней части таблицы, остается вверху до тех пор, пока не будет удалена. Написание сценариев с использованием связывания данных В предыдущем разделе было рассмотрено использование HTML для связы- вания. В данном разделе вы научитесь объединять код сценариев со связы- ванием данных для создания действительных приложений доступа к дан- ным, которые могут выполняться в Internet Explorer 4.0. Обсуждение начи- нается с рассмотрения ADO (ActiveX Data Objects), а затем рассматриваются события, предоставляемые Internet Explorer 4.0 для элементов связывания данных и объектов источников данных. Версия набора записей ADO В примере связывания текущей записи, который был представлен ранее в данной главе, использовались кнопки HTML для перемещения указателя текущей записи вперед и назад. Для события onclick использовался сцена- рий stocklist.recordset.MoveNext(). Данный код ссылается на объект recordset из объекта источника данных stocklist, а затем вызывается метод MoveNext В объекте recordset. Объект recordset в данном случае является версией ADO-Recordset, которая называется здесь ADOR и содержит только объекты recordset и field из полной версии ADO, поставляемой с различными продуктами Microsoft, та- кими как Active Server Pages. Браузер Internet Explorer 4.0 поставляет ADOR для всех объектов источников данных на Web-странице. Как показано в приведенном выше примере, объект recordset доступен из свойства recordset объекта источника данных. Вы можете обратиться к данным в наборе данных ADOR с помощью сцена- риев. Посредством сценариев вы можете изменить установку текущей запи- си и выполнить расчеты, проверку и все функции, которые требуют доступа к данным. Данные, использованные в наборе данных ADOR, не требуется связывать с HTML-элементами на странице. Вы можете использовать набор данных ADOR исключительно для доступа программ к данным из объекта источника данных. Обсуждение особенностей использования ADOR выходит за рамки данной главы. Однако в следующих разделах будут затронуты две ключевые области функциональных возможностей, обычно используемые на Web-страницах: методы перемещения и объекты field.
456 Часть IV. Содержание документа и связывание данных Методы перемещения Методы перемещения позволяют изменять установку текущей записи, таким образом, изменяя значения, отображаемые в связанных элементах. Методы, используемые для перемещения указателя текущей записи, перечислены ниже: Move (Переместить), MoveNext (ПереместитьКСледующей), MovePrevious (ПереместитьКПредыдущей), MoveFirst (ПереместитьКПервой) и MoveLast (ПереместитьКПоследней). Метод Move принимает аргумент для перемете- ния указателя текущей записи в выбранное положение в наборе записей. Функции других методов очевидны из их названия. ADOR позволяет устанавливать указатель текущей записи перед первой записью в наборе данных (bof (beginning of file) — начало файла) или после последней записи в наборе данных (eof (end of file) — конец файла). По- скольку данные положения не имеют связанных с ними данных, то пере- мещение в данные позиции приведет к тому, что все связи на странице бу- дут иметь нулевые значения, что обычно означает отсутствие вывода на эк- ран. Возникновения этой ситуации можно избежать путем проверки текущего положения в наборе записей до перемещения указателя. Приве- денный ниже кол проверяет, является ли текущая запись последней в набо- ре записей, перед переходом к указателю текущей записи: <SCR1PT LANGUAGE”"JavaScript" FOR=NextButton EVENT=onclick> if (stocklist.recordset.AbsolutePosition < stocklist.recordset.RecordCount) stocklist.recordset.MoveNext(); else alert("Already at last record.”); </SCRIPT> ( Примечание ) Положение текущей записи может быть также изменено путем изменения зна- чения свойства AbsolutePosition набора записей. Семейство fields и объект field Семейство fields содержит набор объектов field для набора записей. Объ- ект field прямо соответствует одиночному столбцу данных. Объект field используется для чтения значений данных из столбца для текущей записи набора записей. Например, данные для текущей записи в столбце Last могут быть получены с помощью приведенного ниже кода. Все строки кода воз- вращают одинаковые значения. stocklist.recordset.Fields("Last").value stocklist.recordset.Fields("Last") stocklist.recordset("Last") . • . ..
Глава 15. Связывание данных с помощью HTML 457 Присвоение значения свойству value объекта field модифицирует значе- ние. Приведенный ниже код устанавливает последнюю цену акции в теку- щей записи, равной 103.0: stocklist.recordset("Last") = 103.0; В данном случае также может быть использована любая из трех эквивалент- ных форм записи данной инструкции. Более подробную информацию об ADOR можно найти в Internet Client SDK (Softwa- re Development Kit), который доступен на Web-узле компании Microsoft по адресу www.microsoft.com/ msdn/sdk/inetsdk. События сценариев Браузер Internet Explorer 4.0 предоставляет расширенный набор событий для помощи Web-мастерам при написании сценариев для обработки действий пользователя на страницах со связыванием данных. События набора могут быть разделены на две категории. События первой категории запускаются на элементах потребления данных. Данные события (onbeforeupdate, onafterupdate и onerrorupdate) представлены для проверки вводимой поль- зователем информации. События второй категории (onrowexit, onrcwenter, ondatasetchanged, ondataavailable и ondatasetcomplete) генерируются на объектах источника данных для активизации проверки и обработки, когда текущей становится новая запись или в ответ на синхронную передачу дан- ных клиенту. Дополнительное событие onbeforeunload не является харак- терным для связывания данных, но полезно в приложениях связывания данных. В следующих разделах данные события описаны более подробно. ( Примечание Как и все события в объектной модели динамического HTML события, описан- ные в данном разделе, всплывают вверх по иерархии контейнеров. Обработчи- ки для них могут быть написаны на любом уровне иерархии. Если многочис- ленные объекты источников данных представлены на странице, то Web-мастер может добавить одиночный контейнер для любого события в общем контейне- ре с целью обработки события. Событие onbeforeupdate Событие onbeforeupdate генерируется для HTML-элементов, которые под- держивают обновление данных. (В табл. 15.1 в данной главе приведен спи- сок потребителей данных, которые поддерживают обновление.) Событие onbeforeupdate генерируется, когда пользователь перемещает фокус с эле- мента. значение которого было обновлено и'перед передачей обновленных данных в объект источника данных с помощью агента связывания. Пре- дыдущее значение данных может быть получено из объекта источника дан-
458 Часть IV. Содержание документа и связывание данных ных при помощи набора данных ADOR. Событие onbeforeupdate может быть использовано Web-мастером для выполнения проверки. Если Web- мастер отменяет событие, то фокус остается на элементе и данные не пере- даются в объект источника события. Приведенный ниже код демонстрирует обработчик для события onbeforeupdate. В данном примере проверяется, что значение в текстовом окне HTML лежит в диапазоне от 5 до 15. Если значение лежит за предела- ми данного диапазона, то отображается сообщение об ошибке и событие отменяется. <SCRIPT LANGUAGE^'JavaScript" FOR=textboxl EVENT=onbeforeupdate> if (textboxl.value <511 textboxl.value > 15) 1 alert("Number must be in the range 5 through 15."); returnValue = false; 1 </SCRIPT> Событие onafterupdate Событие onafterupdate также генерируется на HTML-элементах, которые поддерживают обновление. Однако данное событие запускается сразу же после передачи данных из элемента в объект источника данных. Событие onafterupdate не запускается, если отменено событие onbeforeupdate, а со- бытие onafterupdate само по себе не отменяется. Одним из применений события onafterupdate является обновление вычис- ленного значения. Например, пользователь заполнил форму заказа, выбрал элемент и количество. После ввода количества вы можете вычислить общую сумму на основе цены одного элемента и количества заказанных единиц товара. Вы можете выполнить эту задачу в обработчике события onafterupdate текстового окна, в котором введено количество единиц товара: <SCRIPT LANGUAGE^'JavaScript" FOR=quant_tbox EVENT=onafterupdate> line_total.value = quant_tbox.value * itemprice.value; </SCRIPT> Событие onerrorupdate События onbeforeupdate и onafterupdate охватывают передачу данных из HTML-элемента в объект источника данных, но не учитывают редкий слу- чай, в котором передача данных является неудачной. В этом случае возника- ет событие onerrorupdate. События onerrorupdate И onafterupdate ЯВЛЯЮТСЯ взаимоисключающими, то есть событие onafterupdate генерируется только в случае успешной пере-
Глава 15. Связывание данных с помощью HTML 459 дачи данных, а событие onerrorupdate возникает только при срыве передачи данных. Событие onerrorupdate предоставляет Web-мастеру возможность вывести на экран соответствующее сообщение об ошибке при неудачной передаче данных. i4 Примечание Передача данных происходит, когда агент связывания и повторения обнаружи- вает изменение значения связанного элемента. Но агент связывания и повто- рения может не заметить изменение значения сразу же после проведения из- менения. Например, если связанное значение изменяется посредством сцена- рия, то агент связывания и повторения не заметит изменение до тех пор, пока указатель текущей записи не переместится или страница не будет выгружена. Кроме того, поскольку объект или апплет не требуются для генерации уведом- лений, когда значение одного из связанных свойств изменяется, то агент свя- зывания и повторения автоматически передает данные из объекта или аппле- та, когда указатель текущей записи перемещается или страница выгружается, даже если значение не было изменено. Событие onrowexit Событие onrowexit является первым событием в наборе событий, которое генерируется в объекте источника данных. Напомним, что объект источника данных имеет одну текущую запись. В качестве текущей при помощи метода перемещения в ADOR может быть установлена другая запись. Событие onrowexit генерируется в объекте источника событий для извещения о том, что будет перемешен указатель текущей записи. Перед возникновением события onrowexit должны быть выполнены неко- торые действия. Сначала требуется запросить перемещение указателя теку- щей записи, в общем случае посредством выполнения метода перемещения в наборе записей ADOR. После получения запроса агент связывания прове- ряет каждый связанный HTML-элемент для выявления измененных данных в текущей записи. Это выполняется путем сравнения значения в элементе со значением в столбце объекта источника данных. Если столбцы различа- ются, то агент связывания генерирует событие onbeforeupdate на данном элементе. Если событие отменяется, то действия прекращаются и указатель текущей записи остается на прежнем месте. Если событие onbeforeupdate не отменяется, то событие onafterupdate генерируется в элементе. Данный процесс повторяется для каждого связанного HTML-элемента. После син- хронизации всех элементов событие onrowexit генерируется на объекте ис- точника данных. Событие onrowexit можно отменить. При этом указатель текущей записи остается на прежнем месте. Событие onrowex.it полезно для выполнения проверки на высоком уровне или для пересчета столбцов объекта источника данных, которые не связаны, но являются базовыми для значений в других столбцах.
460 Часть IV. Содержание документа и связывание данных Приведенный ниже пример содержит обработчик события onrowexit: <SCRIPT LANGUAGE»”JavaScript"> function myrowexit() ( if (stocklist.recordset("Last") * stocklist.recordset("Shares") > my_cash_balance) { alert("Purchase exceeds cash position in your account."); returnValue = false; I } </SCRIPT> Событие onrowenter Как видно по имени, событие onrowenter (переход на строку) возникает по- сле перемещения указателя текущей записи. При генерации данного собы- тия все данные из новой текущей записи будут представлены в HTML- элементах, связанных с объектом источника данных. Событие onrowenter нельзя отменить, поскольку данные из новой текущей записи уже отображаются на экране. Событие onrowenter полезно для вы- числяемых полей на основе элементов данных в строке. Приведенный ниже пример демонстрирует использование события onrowenter: <SCRIPT LANGUAGE»"JavaScript"> function myrowenter() ( total_value.text = stocklist.recordset("Price") * stocklist.recordset("Shares"); </SCRIPT> ' • Событие ondatasetchanged Web-мастерам необходимо точно знать, когда объект источника данных го- тов передавать данные, и событие ondatasetchanged является первым из трех событий, которые помогают в рещен ии этой задачи. Событие ondatasetchanged генерируется на объекте источника данных, как только данные становятся доступными, извещая о возможности получения набора данных ADOR из объекта источника данных. Событие ondatasetchanged нельзя отменить. Помимо запуска при первом отображении HTML-странипы, событие ondatasetchanged генерируется, когда объекты источника данных выполняют манипуляции с данными. Эти манипуляции могут выполняться в ответ на изменение порядка в наборе данных, вызванным сортировкой, или на изме- нения в основной структуре набора данных (число строк или столбцов, или имен столбцов), вызванное отбором.
Глава 15. Связывание данных с помощью HTML 461 Событие ondataavailable Web-мастер может получить уведомление о поступлении дополнительных данных из объекта источника данных при помощи обработки события ondataavailable. Событие ondataavailable генерируется, когда данные из объекта источника данных были получены браузером. Событие ondataavailable НСЛЬЗЯ ОТМенИТЫ Объект источника данных определяет частоту возникновения события ondataavailable. По соображениям производительности большинство объек- тов ИСТОЧНИКОВ данных НС запускают событие ondataavailable для каждой отображаемой записи. Напротив, объекты источников данных будут соби- рать ряд строк и столбцов в виде блока и запускать событие ondataavailable для данного блока строк. Событие ondataavailable, однако, не указывает число доступных строк и их положение в наборе данных. Данная информа- ция должна быть определена непосредственно из набора данных ADOR. Событие ondataavailable может быть использовано для расчета текущей суммы записей по мере их поступления или для выполнения операций сце- нариев по мере поступления данных в браузер: <SCRIPT LANGUAGE=="JavaScript"> var count; function myondataavailable() ( total_stocks.value = stocklist.recordset.RecordCount; ) </SCRIPT> Событие ondatasetcomplete Последним в наборе асинхронных событий является событие ondatasetcomplete. Являясь, возможно, самым полезным асинхронным со- бытием, событие ondatasetcomplete уведомляет Web-мастсра о завершении асинхронной передачи и доступности всего набора данных. Событие ondatasetcomplete устанавливает свойство reason объекта event с целью сообщения Web-мастеру о состоянии передачи. В табл. 15.3 перечис- лены три возможных значения для свойства reason. t Таблица 15.3. Значения свойства reason Значение Описание О Передача была завершена без ошибо(< 1 Пользователь прервал передачу. В общем случае, данное прерывание возникает, когда пользователь нажимает кнопку Stop (Стоп) на странице
462 Часть IV. Содержание документа и связывание данных Таблица 15.3 (окончание) Значение Описание 2 Передача привела к возникновению ошибки. Это общий случай для различных срывов передачи, включая невозможность связи с хостом . или разрыва соединения Событие onbeforeunload Событие onbeforeunload не является характерным для связывания данных, но его обработка может быть полезна для предотвращения потери данных на страницах со связыванием данных. Некоторые объекты источников дан- ных могут кэшировать обновления данных, которые они поставляют клиен- ту, до тех пор, пока метод не будет вызван на объекте для сохранения об- новленных значений на сервере. Поскольку данные значения могут быть кэшированы, пользователь может попытаться покинуть страницу до сохра- нения обновленных значений. Событие onbeforeunload может быть исполь- зовано для того, чтобы попросить пользователя отменить переход во избе- жание потери измененных данных. Работа события onbeforeunload отчасти отличается от других событий, кото- рые обсуждались ранее. Событие onbeforeunload запускается в ответ на за- прос пользователя для перехода на новую страницу. Например, когда поль- зователь нажимает гиперссылку, щелкает по кнопке Back (Назад) или For- ward (Вперед) или вводит новый URL в адресной строке. Событие onbeforeunload запускается на объекте window до события unload на страни- це. Когда возникает данное событие, Web-мастер может установить значе- ние свойства returnvalue объекта event равным строковому значению, ко- торое будет отображено на компьютере пользователя наряду со стандартным сообщением браузера, объясняющим, что пользователь может отменить за- прашиваемый переход. В общем случае Web-мастеры устанавливают возврат сообщения о том, что продолжение навигации приведет к отмене кэширо- ванных изменений. Если пользователь решает отменить навигацию, то стра- ница остается на экране и пользователь может взаимодействовать с ней так, как будто методы гиперссылки или перехода не были вызваны. Если поль- зователь продолжает навигацию, то страница выгружается и изменения дан- ных отменяются. Отмена события unload требует участия пользователя Должен ли Web-мастер иметь возможность просто отменить событие unload, не спрашивая мнение пользователя? Ответ наЪтот вопрос находится в цен- тре проблем безопасности операционной системы. Если бы Web-мастер имел возможность отмены события unload, то было бы можно создать стра-
Глава 15. Связывание данных с помощью HTML 463 ницу, которая никогда не была бы выгружена. То есть, событие unload все- гда бы отменяло навигацию. Единственным способом для пользователя по- кинуть данную страницу было бы прекращение процесса браузера, что явля- ется нарушением базовой целостности операционной системы, поскольку пользователь всегда имел бы возможность управления своей локальной ма- шиной и процессами. Событие onbeforeunioad может быть отменено, но именно пользователь принимает решение об отмене события unload, а не Web-мастер. Web-мастер имеет только возможность вывода информацион- ного сообщения для пользователя. Дополнительные элементы После ознакомления с основами перейдем к изучению дополнительных элементов связывания данных, которые позволяют создавать более сложные страницы, похожие на приложения. Обновление данных Объект источника данных может разрешить пользователю обновлять по- ставляемые данные. Когда пользователь обновляет данные в элементе, свя- занном с объектом источника данных, агент связывания сохраняет модифи- цированное значение в объекте источника данных. Объект источника дан- ных может затем сохранить данные измененные значения в основном источнике данных. В общем случае объекты источников данных поддерживают обновления данных, предоставляя пользователю возможность изменения данных, сохра- няемых в локальном кэше. Объект источника данных может затем выбрать момент обновления данных в основном источнике данных: данные могут быть обновлены немедленно или в пакетном режиме. В кэше могут быть сохранены изменения в отдельной ячейке, отдельной строке или во всем наборе данных. Режим работы объекта источника данных будет выбран в зависимости от того, поддерживается ли соединение с основным источни- ком данных. Когда кэшируется весь набор данных, то объекты источников данных обычно предоставляют метод, который Web-мастсры могут исполь- зовать для сохранения кэшируемых данных. RDS является примером объекта источника данных, который обеспечивает возможность обновления данных. RDS работает в сочетании с компонентом серверной стороны, который активизирует доступ к источникам данных ODBC (Online Database Connectivity — средства связи с открытыми базами данных). RDS сохраняет весь набор данных (результат запроса SQL) в кэше локальной памяти. Помимо сохранения данных RDS сохраняет сопутствую- щую информацию для решения конфликтов, когда многочисленные пользо-
464 Часть IV. Содержание документа и связывание данных ватели одновременно модифицируют одни и те же значения данных. Дан- ные, изменяемые пользователем, отправляются вместе с сопутствующей ин- формацией серверному компоненту, который выполняет обновление базы данных. RDS может быть использована для построения сложных приложе- ний клиент/сервер при помощи HTML и сценариев. ( Примечание ) Примеры приложений, написанных с использованием RDS, можно найти на Web-узле компании Microsoft по адресу www.microsoft.com/data. Серверные компоненты можно получить бесплатно по тому же адресу. Клиентские компо- ненты RDS являются составным элементом браузера Internet Explorer 4.0 и ин- сталлируются в минимальной конфигурации браузера. Свойство recordNumber Свойство recordNumber доступно для всех элементов, которые являются ча- стью шаблона таблицы с повторением. Напомним, что при использовании таблицы с повторением содержание таблицы используется как шаблон и повторяется для каждой записи в наборе записей. Каждый экземпляр повто- рения называется экземпляром шаблона (template instance). Для всех элемен- тов в экземпляре шаблона (включая элементы, которые не являются связан- ными данными, такие как теги <tr> и <td>), свойство recordNumber обеспе- чивает номер записи из набора записей, который генерируется элементом. Свойство recordNumber соответствует непосредственно свойству Absoluteposition набора записей ADOR. Используя свойство recordNumber для установки значения свойства Absoluteposition в наборе записей, Web- мастер может получить доступ к дополнительным элементам данных из того же столбца набора данных. Вам требуется установить значение свойства Absoluteposition, поскольку ADOR разрешает доступ только к полям теку- щей записи. Свойство recordNumber не является закладкой. Это свойство изменяется в результате вставки или удаления строк из кэша локального клиента. Ис- пользуя ADOR, однако, Web-мастер может получить закладку для столбца, используя СВОЙСТВО recordNumber: <SCRIPT LANGUAGE»”JavaScript"> var clone_rs = stocklist.recordset.cloneO; clone rs.AbsolutePosition = textboxl.recordNumber; var bkmk = clone_rs.Bookmark; </SCRIPT> Данная закладка всегда указывает текущую запись в наборе записей, незави- симо от того, вставлены или удалены строки.
Глава 15. Связывание данных с помощью HTML 465 Свойство recordNumber может быть также использовано для помощи при навигации в семействе элементов в таблице с повторением. Вы можете уста- новить уникальное имя для элемента HTML путем включения атрибута id в тег элемента. Когда вы даете имя элементу в шаблоне таблицы с повторени- ем, результатом является семейство элементов с одинаковым идентификато- ром (id), поскольку шаблон повторяется для каждой записи в наборе дан- ных. Свойство recordNumber может быть использовано в сочетании со сценарием для отображения подробной информации из записи, соответст- вующей выбранному элементу. Например, вместо одновременного просмот- ра всех данных по акциям, вам требуется просмотреть подробную информа- цию для определенной акции. Вы можете включить в таблицу кнопки се- лектора для выбора акции и затем установить выбранную акцию в качестве текущей записи с целью отображения подробных данных, используя приве- денный ниже код: <BODY TOPMARGIN=0 LEFTMARGIN=4О BGCOLOR="#FFFFFF"> <FONT FACE="verdana,arial,helvetica" SIZE=2> <H2>Record Number</H2> <TABLE> <TR> <TD VALIGN=top> CTABLE ID="stocktbl" DATASRC="#stocklist" BORDER=1> <THEAD> <TR ONCLICK="sort(); "> <TD>&nbsp; <TD CLASS=thdxDIV ID=Symbol>Symbol</DIVx/TD> <TD CLASS=thdxDIV ID=Last>Shares</DIVx/TD> <TD CLASS=thdXDIV ID=Volume>Volume</DIVX/TD> </TR> </THEAD> <TBODY> <TR> <TD> <BUTTON CLASS=sb ONCLICK="setrn(this);"> <B>show</B> </BUTTON> </TD> <TDXA DATASRC="Website”XSPAN DATAFLD="Symbol"> </SPANx/A> </TD> <TD ALIGN=rightxDIV DATAFLD="Shares"X/DIV></TD> <TD ALIGN=right> <SPAN DATAFLD="Volume" DATAFORMATAS=HTML> </SPAN>
466 Часть IV. Содержание документа и связывание данных </TD> </TR> </TBODY> </TABLE> </TD> <TD VALIGN=top> <B>Company Name:</B> <SPAN DATASRC="#stocklist" DATAFLD="CompanyName"> </SPAN> <BR> <B>Last Updated:</B>. <SPAN DATASRC="#stocklist" DATAFLD="DateUpdated"> </SPAN> <BR> <B>Open:</B> <SPAN DATASRC="#stocklist" DATAFLD="Open"> </SPAN> <BR> <B>High:</B> <SPAN DATASRC="#stOcklist" DATAFLD="High”> </SPAN> <BR> . . <B>Low:</B> <SPAN DATASRC=''#stocklist" DATAFLD="Low"> </SPAN> <BR> <B>PE Ratio:</B> <SPAN DATASRC="#stocklist” DATAFLD=”PERatio"> </SPAN> <BR> <B>Chart:</B> <IMG ALIGN=top DATASRC="#stocklist” DATAFLD=*'Chart"> </SPAN> </TR> </TABLE> <SCRIPT LANGUAGE3*"JavaScript"> function setrn(button) ( stocklist.recordset.AbsolutePosition = button.recordNumber; } </SCRIPT> </BODY> На рис. 15.5 показана подробная информация, которая выводится на стра- нице рядом с таблицей.
Глава 15. Связывание данных с помощью HTML 467 jQ Record Number Micioxoll Internet Exploiei j . £е £dt!. Цр* , .fi.o Fjvaxr, Цф, Record Number show show show show show show show show ilSvmbol aapl amzn CSCO ibm Intc msft nscp [ord sunw Shares -200. Volume 4302800 500 299000 500 5469200 600 2000 5000 4000800 21846700 7364100 -100 1768800 200! 4345400: 400! 5014000 -700; 829600 yhoo show Company Name: INTEL CORPORATION Last Updated: 8/2/97 8:35 AM Open: 92.75 High: 94.31 Low: 90.5 PE Ratio: 24.45 Chart: Price Hute- (&ЯМГ. 1ЙМ?) Compare v»ik' B.port DMa Chart • Feried •WTC 1 V Рис. 15.5. Свойство recordNumber используется для отображения определенной записи в таблице с повторением Изменение атрибутов связывания Динамический HTML представляет свойства, которые соответствуют атри- бутам и стилям тегов HTML-элементов. Атрибуты связывания данных не являются исключением. Web-мастер имеет возможность добавления, удале- ния и изменения свойств связывания данных для HTML-элементов после вывода страницы на экран. Более того, используя динамический HTML, Web-мастер может также добавлять и удалять объекты источника данных на странице. Единственным недостатком данного соответствия является то, что атрибуты datasrc, datafld и dataformatas не могут быть изменены для элементов внутри таблицы с повторением. Вы можете обойти данное ограничение пу- тем преобразования таблицы в стандартную HTML-таблицу. Сначала удали- те атрибут datasrc из таблицы. Таблица переходит к состоянию без повто- рения и содержит только шаблон. Элементы внутри шаблона, хотя они и не связаны, могут быть изменены. Атрибут datasrc может быть затем добавлен обратно в таблицу для повторной установки режима повторения. Используя
468 Часть IV. Содержание документа и связывание данных мультимедиа-расширения браузера Internet Explorer 4.0, Web-мастер может также приостановить повторное отображение таблицы, так что данная се- рия шагов будет происходить без многочисленных обновлений содержания экрана. Примечание ) Дополнительная информация о связывании данных может быть получена из раздела, посвященному Internet Explorer 4.0, на Web-узле компании Microsoft по адресу www.mlcrosoft.com. Примеры можно также найти по тому же адресу.
Приложение Словарь английских технических терминов Applet Апплет Argument Аргумент Attribute Атрибут Begin tag - Открывающий тег Binding Связь Binding and repetition agent Агент повторения и замещения Browser Браузер Bulleted list Маркированный список Cascading Style Sheets (CSS) Каскадные таблицы стилей Check box Флажок Clipping region Collection Область вырезки Семейство Combo box Раскрывающееся поле со списком Constructor Конструктор Content Содержание Control Элемент управления Current record binding Связывание текущей записи Custom behavior Индивидуальная модель поведения Data binding Document Type Definition (DTD) Связывание данных Определение типа документа
470 Приложение А. Словарь английских технических терминов Encapsulation End tag Entity Event handler Event model Function Global Style Sheet HyperText Markup Language (HTML) Inline style sheet Intrinsic control Layout Linked Style Sheet List box Multiple-select list box Object model Offset Offset parent Overlapping Paged table Paged table binding Pointer Prefix Presentation rules Provider Pseudo-class Radio button Repeated table Repeated table binding Routine Scope of influence Инкапсуляция Закрывающий тег Компонент Обработчик событий Модель событий Функция Таблица глобальных стилей Язык разметки гипертекста Таблица внутренних стилей Внутренний элемент управления Схема размещения Таблица связанных стилей Поле со списком Поле со списком для множественного выбора Объектная модель Смещение Относительный предок Перекрытие Таблица с замещением Связывание таблицы с разбиением Указатель Префикс Правила представления Провайдер Псевдокласс Переключатель Таблица с повторением Связывание таблицы с повторением Процедура (или подпрограмма) Область действия
Приложение А. Словарь английских технических терминов 471 Script Scripting language Scrolling sidebar Search engine Selector Shadowed Sidebar Single-select list box Standard Generalized Markup Language (SGML) Tabbing order Tag Unmatched tag Web author Web page Сценарий Язык написания сценариев Маркер полосы прокрутки Поисковая машина Селектор Выделенный тенью Врезка Поле со списком для одиночного выбора Стандартный обобщенный язык разметки Последовательность перехода Тег Непарный тег Web-мастер Web-страница

Предметный указатель с cookie, 171 А Абсолютное позиционирование, 347 Активная ссылка, 167 Анимация изображений, 242 В Владелец редактирования текста, 412 Внедренные объекты, 425 Внутренние элементы управления, 20; 267 Внутренний стиль, 29 Врезка, 35 Всплывание событий, 71 Всплывающая подсказка, 23 Встроенный фрейм, 152 д Действия по умолчанию, 71 Дерево анализа, 214 воспроизведения, 375 Динамический стиль, 29 Динамическое переформатирование документа, 51 Динамическое содержание, 387 И Информация анализа, 213 воспроизведения, 213 К Карта изображения, 245 Кнопка-переключатель, 268 Компонент, 43 Константы на основе HTML, 220 Контекст воспроизведения, 374 Концевой узел, 90 Л Логический размер документа, 226 м Мета-информация, 170 Методы отображения данных, 334 Модель поведения, 9 И Набор фреймов, 146 Непросмотренная ссылка, 167 Нераспознаваемые элементы, 198; 212 О Область вырезки, 352 действия элемента, 195 Объектная модель динамического HTML, 46 Окно, типы, 133 Определение типа документа, 42 Отключенные элементы управления, 24 Относительное позиционирование, 347 Относительный предок, 374
474 Предметный указатель п Переадресация на клиентской стороне, 62 Перекрывающиеся элементы, 200 Перечислимые типы данных, 211 Поле со списком, 292 Последовательность каскадирования, 33 перехода, 23 Потребитель данных, 430 Правила представления, 31 Просмотренная ссылка, 167 Псевдокласс, 33; 238 Р Разбиение таблицы, 453 , . , • с Связывание данных, 429 событий, 72 таблицы с повторением, 432 текущей записи, 432 Селектор, 31 Событие, 71 Соглашение об именовании, 210 Списки, 202 Стадии загрузки, 179 Стандартный обобщенный язык разметки, 17 Статическое позиционирование, 346 т Таблица глобальных стилей, 30; 313 связанных стилей, 31 Таблицы каскадных стилей, 28 Текстовые анимации, 344 Типы данных, 208 позиционирования, 346 Указатели функций, 66 Ф Физический размер документа, 226 Флажок, 268 Фокус, 113 Фреймы без границ, 150 э Экземпляр шаблона, 464 Элемент управления только для чтения, 24 Я Язык разметки гипертекста, 17
Описание компакт-диска Информация о Web-узле автора книги Дополнительную информацию о динамическом HTML можо найти на Web-узле автора книги по адресу: http://www.insideDHTML.coni. Узел содержит до- полнительные примеры и комментарии по динамическому HTML. Содержание компакт-диска □ Примеры файлов из книги □ Электронная версия данной книги ’ . - . О Браузер Microsoft Internet Explorer 4.0 " ' : □ Набор разработчика Microsoft Internet Explorer 4.0 SDK Как использовать данный компакт-диск Примеры файлов из книги Для просмотра примеров вы можете использовать индексную страницу, ко- торая находится в файле d:\samples\samples.htm. Для просмотра файла мож- но использовать текстовый редактор или HTML-редактор. Можно также выбрать в окне браузера Internet Explorer 4.0 в меню View (Вид) команду Source (В виде HTML). Вы можете скопировать примеры файлов на свой жесткий диск. Чтобы из- менить файл, сбросьте свойство Read-only (Только для чтения). Для этого откройте Windows Explorer (Проводник), щелкните по названию файла пра- вой кнопкой мыши и выберите в контекстном меню команду Properties (Свойства). Затем сбросьте флажок Read-only (Только чтение) в разделе Attributes (Атрибуты) диалогового окна Properties (Свойства).
476 Описание компакт-диска Электронная версия книги Для чтения электронной версии данной книги ее следует установить с CD-ROM. Запустите команду d:\setup (где d — это буква вашего привода CD-ROM) и следуйте инструкциям. Если Internet Explorer 4.0 не установлен, то следует его установить. (Internet Explorer 4.0 необходим для чтения элек- тронной версии книги). По завершении инсталляции для чтения книги сле- дует щелкнуть по значку на рабочем столе или выбрать в меню Start (Пуск), пункты Programs (Программы), Microsoft Press Titles, Inside Dynamic HTML. Браузер Microsoft Internet Explorer 4.0 При установке электронной версии книги браузер Internet Explorer 4.0 будет установлен автоматически. Для установки Internet Explorer 4.0 запустите команду d:\ie40\ie4setup (где d — это буква привода вашего CD-ROM) и следуйте инструкциям по установке. После установки Internet Explorer и перезагрузки компьютера вы сможете использовать браузер Internet Explorer 4.0 для работы с примерами файлов и просмотра остальной части содержимого компакт-диска. Набор разработчика Microsoft Internet Explorer 4.0 SDK Вы можете установить набор разработчика Microsoft Internet Explorer 4.0 SDK на свой жесткий диск или просматривать его с компакт-диска. От- кройте файл d:\INetSDK\default.htm (где d — это буква вашего привода CD-ROM) и выберите в меню необходимые параметры. Некоторые старые приводы CD-ROM не могут читать длинные имена и пу- ти каталогов с глубиной вложенности более 8 уровней. Если у вас установ- лен такой привод CD-ROM, и при просмотре файлов INetSDK возникли проблемы, то надо установить INetSDK на жесткий диск. При инсталляции используются сжатые файлы с короткими именами, которые ваш CD-ROM сможет прочитать. При установке файлов на жесткий диск программа ин- сталляция INetSDK распаковывает и переименовывает их. Служба поддержки Информация о службе поддержки издательства Microsoft Press Были приняты все меры для того, чтобы обеспечить корректность информа- ции в книге и на прилагаемом CD. С исправлениями в книгах Microsoft Press вы можете ознакомиться на Web-узле по адресу: http://mspress.microsoft.com/mspress/support/
Описание компакт-диска 477 С комментариями, вопросами и предложениями относительно данной книги или прилагаемого компакт-диска, обращайтесь в Microsoft Press по адресу электронной почты: MSPINPUT@MICROSOFT.COM или по обычному почтовому адресу: Microsoft Press Attn: INSIDE DYNAMIC HTML Editor One Microsoft Way Redmond, WA 98052-6399 . '•,, > Обратите внимание, что по данным адресам не осуществляется поддержка продукта. Информация о поддержке браузера Internet Explorer 4.0 Справочную информацию по работе с браузером Internet Explorer 4.0 вы можете получить, связавшись со службой поддержки Microsoft Technical Support по адресу: http://www.microsoft.com/support/ В США вы можете получить техническую консультацию по работе с браузе- ром Internet Explorer 4.0 по телефону (425) 635-7123 в рабочие дни с 6 утра до 6 вечера по местному времени. Для получения справочной информации за пределами США обращайтесь в местные отделения Microsoft. Компания Microsoft также размещает информацию о браузере Internet Explorer 4.0 по адресу: http://www.microsoft.com/ie/

Содержание ВВЕДЕНИЕ......................................................□ Создание интерактивных страниц..............................5 Языки программирования....................................6 Новые элементы............................................7 Определение HTML-документа..................................9 Структура и стиль.........................................9 Структура книги............................................11 Часть I. HTML и программирование сценариев...............11 Часть II. Структура документа............................11 Часть III. Стиль документа и анимация....................12 < Часть IV. Содержание документа и связывание данных.........12 Прилагаемый компакт-диск.................................12 Поддержка..................................................13 ЧАСТЬ I. HTML И ПРОГРАММИРОВАНИЕ СЦЕНАРИЕВ...................15 ГЛАВА 1. ОБЗОР HTML И CSS....................................17 Новые элементы HTML........................................18 Внедрение индивидуальных объектов........................19 Изменения в формах и облегчение доступа..................20 Добавление надписей и клавиш доступа.....................21 Добавление поясняющего текста в элемент..................23 Управление последовательностью перехода..................23 Отключение элементов управления..........................24 Новый элемент Button.....................................25 Элемент Fieldset.........................................26 Кнопки Default и Cancel..................................27 Улучшенный элемент бегущей строки........................28 Связывание данных........................................28 Каскадные таблицы стилей...................................28 Внутренние стили.........................................29 Таблицы глобальных стилей................................30 Таблицы связанных стилей.................................31
480 Содержание Определение таблицы стилей........................;............31 Псевдоклассы................................................33 Последовательность каскадирования...........................33 Элементы CSS................................................33 Выравнивание текста.........................................34 Маркированные списки........................................34 Создание врезок.............................................35 Сравнение свойств visibility и display......................36 Управление курсором.........................................37 Поддержка CSS для внутренних элементов.......................38 . Внедрение индивидуальных шрифтов............................38 Пользовательские установки.................................. 39 Позиционирование CSS........................................41 Эффекты фильтров и перехода.................................41 Проверка определения типа документа HTML......................41 Определение элемента........................................ 42 Определение атрибутов.......................................43 Определение компонента......................................43 ГЛАВА 2. ОСНОВЫ СЦЕНАРИЕВ HTML.................................46 Иерархия объектов динамического HTML..........................47 Эволюция иерархии динамического HTML........................47 Эволюционное (революционное) развитие динамического HTML.....49 Поддержка старых версий браузеров...........................49 Динамическое переформатирование.............................51 Создание сценариев............................................51 Элемент Script..............................................52 Библиотеки сценариев........................................54 Немедленное выполнение программы............................54 Местоположение сценариев в документе........................56 Доступность объектов........................................57 Отложенное выполнение сценария..............................58 Языки написания сценариев...................................58 Скрытие сценариев от браузеров низкого уровня...............59 Переадресация на стороне клиента............................62 Выбор языка: JavaScript или VBScript..........................62 JavaScript..................................................63 Передовые методы JavaScript...................................64 Добавление свойств в объекты................................64 Указатели функций...........................................66 Проверка поддержки..........................................68 Соглашения об именовании свойств и функций..................68 Сценарии и безопасность в Web................................. 69
Содержание 481 ГЛАВА 3. МОДЕЛЬ СОБЫТИЙ ДИНАМИЧЕСКОГО HTML....................71 Общая модель событий........................................72 Всплывание событий.........................................73 Действия по умолчанию......................................74 Связывание событий..........................................74 Атрибуты событий...........................................75 Поддержка общих событий...................j................76 Связывание событий в стиле Visual Basic....................77 Определение языков написания сценариев в атрибутах событий.78 События как свойства.......................................79 Расписание связывания событий..............................80 Область действия сценариев.................................81 Разделяемые обработчики событий............................83 Объект event.............................................. 84 Определение события........................................85 Доступ к параметрам посредством объекта event..............86 Координаты мыши............................................86 Информация клавиш и кнопок.................................87 Программирование стандартных пользовательских событий........88 События мыши...............................................88 Событие прокручивания..................................... 94 События фокуса.............................................95 Событие help...............................................95 Примеры событий.............................................96 Event Tutor................................................96 Event Broadcaster..........................................99 ГЛАВА 4. ОКНО БРАУЗЕРА.......................................104 Объект window..............................t...............105 Ссылка на объект window...................................105 Свойства document и event.................................106 Глобальные переменные и определяемые пользователем свойства.106 Установка имени окна......................................107 Передача строк программного кода..........................107 Среда окна.................................................107 Строка состояния..........................................107 Кнопки Back и Forward.....................................109 Местоположение окна.......................................109 Информация экрана.........................................111 События окна...............................................112 События состояния документа.......*.........................112 События фокуса............................................113 Обработка ошибок..........................................115
482 Содержание Пользовательские события.................................116 Определение событий окна................................117 События таймера..........................................117 Использование таймеров..................................119 Свойства clientinformation и navigator...................123 Информация о производителе клиентского компьютера.......124 Окна и объект navigator.................................127 Установки пользователя..................................127 Новые свойства объекта navigator........................128 ГЛАВА 5. УПРАВЛЕНИЕ ОКНОМ И ФРЕЙМОМ........................129 Манипулирование окнами...................................130 Прокручивание окна......................................131 Создание новых окон......................................132 Немодальные окна........................................134 Модальные и индивидуальные диалоговые HTML-окна.........135 Элементы окна...........................................140 Закрытие окна...........................................144 Создание диспетчера окон................................144 Манипулирование наборами фреймов.........................146 Создание наборов фреймов................................147 Сценарии для наборов фреймов............................155 Моделирование браузера..................................160 Особые случаи событий....................................162 ЧАСТЬ II. СТРУКТУРА ДОКУМЕНТА............................ 163 ГЛАВА 6. ДОКУМЕНТ HTML.....................................165 Ссылка на объект document................................166 Изменение цветов документа...............................167 Действительные значения цветов..........................168 Выбор цвета.............................................168 Отражение атрибутов HTML как свойств....................170 Доступ к метаинформации о документе......................170 Размер файла............................................171 Заголовок...............................................171 Местоположение источника................................172 Дата....................................................172 Тип MIME................................................174 Cookies.................................................174 Родительское окно.......................................178 Доступность документа...................................179
Содержание 483 МОДИФИКАЦИЯ ПОТОКА HTML..................................181 Запись HTML в поток.....................................182 Запись сценариев в поток................................183 ГЛАВА 7. СЕМЕЙСТВА ЭЛЕМЕНТОВ ДОКУМЕНТА.....................184 Использование семейств...................................185 Размер семейства........................................186 Доступ к элементам......................................186 Встроенные семейства....................................191 Метод tags..............................................192 Семейство all в документе с набором фреймов.............193 Структура и семейства HTML...............................194 Построение семейства all................................194 Область действия........................................195 Неявные элементы........................................196 Разделение между Head и Body............................196 Нераспознаваемые элементы...............................198 Непарные закрывающие теги...............................199 Перекрывающиеся элементы................................200 Содержание без тегов....................................201 Недействительный HTML...................................201 Списки..................................................202 ГЛАВА 8. СЦЕНАРИИ И ЭЛЕМЕНТЫ...............................205 Идентификация элементов..................................206 Доступ к атрибутам элемента..............................208 Типы данных.............................................208 Информация анализа.......................................213 Определение иерархии контейнеров HTML...................213 Свойство source Index...................................214 Создание дерева анализа.................................214 Свойство document.......................................217 Создание новых элементов.................................217 Настройка элементов......................................218 Действия по умолчанию...................................218 Настройка существующих элементов........................219 Определяемые пользователем элементы.....................219 ГЛАВА 9. ПРОГРАММИРОВАНИЕ ИНДИВИДУАЛЬНЫХ ЭЛЕМЕНТОВ..................................................223 Программирование элементов Body и Frameset...............224 Свойство body ..........................................224 Доступ к свойству body..................................225 Различие между содержанием body и frameset..............226
484 Содержание Окно клиента и размер документа..........................226 События окна.............................................228 Программирование содержания тела документа...............230 Программирование содержания набора фреймов...............230 Программирование элемента anchor..........................232 Свойство href............................................233 События элемента Anchor..................................234 Настройка ссылок на многочисленные фреймы.................236 v Псевдоклассы для якорей..................................238 Удаление якорей..........................................238 Программирование элемента Link............................239 Документ links.htm.......................................240 Документ navigate.htm....................................241 Документ contents, htm...................................241 Программирование элементов IMG и Мар......................242 Анимация изображений.....................................242 Карты изображений........................................245 Программирование элемента Marquee.........................253 Свойства анимации бегущей строки.........................254 События бегущей строки...................................255 Методы Marquee...........................................255 Программирование элемента Object..........................256 Обработка конфликтов свойств.............................256 Альтернативный HTML......................................257 События объекта..........................................257 Программирование элемента Table...........................257 Объект table.............................................258 Семейства rows и cells...................................259 Событие onresize.........................................262 Таблицы глобальных стилей................................262 Создание календаря.......................................262 ГЛАВА 10. ФОРМЫ И ВНУТРЕННИЕ ЭЛЕМЕНТЫ УПРАВЛЕНИЯ ....267 HTML-ФОРМЫ................................................268 Область действия форм....................................269 Программирование элемента Form...........................270 Передача содержания формы.............................. 272 Сброс содержания формы...................................276 Надо ли использовать элемент Form?.......................277 Скрытие и отображение внутренних элементов управления....277 Взаимодействие с отключенными внутренними элементами управления...............................................278 Программирование текстовых элементов Input................279 Доступ к содержанию элемента управления..................280
Содержание 485 Элемент загрузки файлов.........................:.......280 Проверка введенной пользователем информации.............280 Форматирование введенной пользователем информации.......286 Использование элементов ввода пароля....................287 Программирование элементов списков........................288 Определение поля со списком.............................288 Добавление стилей в поле со списком.....................289 Связь списка с отправляемым значением...................290 Программирование содержания списка......................290 Программирование множественного выбора в поле со списком.292 Программирование списков с использованием КНОПОК-ПЕРЕКЛЮЧАТЕЛЕЙ И ФЛАЖКОВ...........................294 Кнопки-переключатели....................................295 Флажки..................................................296 Событие onclick.........................................298 Программирование элементов командных кнопок...............298 Определение кнопок по умолчанию и отмены.............. 299 События кнопок и форм...................................299 Создание кнопок при помощи элемента Button..............300 Программирование элементов Label и Fieldset...............301 Элемент Label и события onclick.........................301 ЧАСТЬ III. СТИЛЬ ДОКУМЕНТА И АНИМАЦИЯ...................L.303 ГЛАВА 11. ДИНАМИЧЕСКИЕ СТИЛИ................................305 Динамические стили и CSS..................................306 Свойства таблиц стилей....................................307 Составные свойства......................................307 Свойство cssText...................................... 308 Изменение свойств.......................................309 Внутренние стили........................................ 309 Изменение атрибута class..................................310 Таблицы глобальных стилей.................................313 Семейство styleSheets...................................314 Ссылка на таблицу стилей............................... 314 Список альтернативных таблиц стилей.....................315 Таблицы стилей, зависящие от среды......................319 Свойство cssText объекта styleSheet.....................320 Семейство rules.........................................321 Импортированные таблицы стилей....*.....................323 Добавление новых таблиц стилей......................... 323 События таблицы стилей..............:...................327
486 Содержание АДАПТИВНЫЕ МЕТОДЫ РАЗМЕЩЕНИЯ............................329 Методы отображения данных...............................334 Использование указателей мыши для выделения содержания.334 Скрытие и отображение данных...........................335 Развертывание и свертывание списков....................337 Создание разворачиваемой таблицы содержания............338 Методы анимации текста..................................344 ГЛАВА 12. ДИНАМИЧЕСКОЕ ПОЗИЦИОНИРОВАНИЕ...................346 Позиционирование CSS....................................347 Свойства позиционирования CSS..........................348 Позиционируемые элементы...............................349 Определение системы координат..........................350 Области вырезки........................................352 Свойство overflow......................................353 Программирование позиционирования CSS...................356 Свойства позиционирования CSS..........................356 Абсолютное позиционирование............................357 Относительное позиционирование.........................368 Контекст воспроизведения................................373 Демонстрация контекста воспроизведения.................377 Свойства смещения относительно позиционированных элементов.378 Определение отображения элемента.......................379 Прокручивание элемента.................................379 Идентификация элемента в выбранном положении...........380 Элемент Мар............................................380 Выравнивание относительно позиционированных элементов..381 ЧАСТЬ IV. СОДЕРЖАНИЕ ДОКУМЕНТА И СВЯЗЫВАНИЕ ДАННЫХ....................................................385 ГЛАВА 13. ДИНАМИЧЕСКОЕ СОДЕРЖАНИЕ.........................387 Манипулирование содержанием.............................388 Свойства динамического содержания.......................388 HTML и свойства текста.................................390 Применение свойств динамического содержания............391 Использование методов Adjacent.........................396 Доступ к содержанию....................................400 Динамическое содержание и метод document.write..........402 Создание строки заголовка..............................403 Расширенные индексы и таблицы содержания...............404
Содержание 487 ГЛАВА 14. ПОЛЬЗОВАТЕЛЬСКИЕ ОПЕРАЦИИ ВЫДЕЛЕНИЯ И РЕДАКТИРОВАНИЯ..........................................411 Введение в объект TextRange.............................412 Охватываемый текст.....................................414 Программирование объекта TextRange......................414 Создание объекта TextRange.............................415 Представление содержания документа.....................416 Связь объекта TextRange со структурой документа........418 Позиционирование объекта TextRange.....................418 Управление объектами TextRange.........................423 Манипулирование закладками.............................425 Внедренные объекты.....................................425 Выбор текстовой области................................425 Доступ к выделенной пользователем области...............426 Выполнение команд.......................................426 ГЛАВА 15. СВЯЗЫВАНИЕ ДАННЫХ С ПОМОЩЬЮ HTML................429 Что ТАКОЕ СВЯЗЫВАНИЕ ДАННЫХ?............................431 Архитектура связывания данных...........................432 Объекты источников данных..............................432 HTML-расширения связывания данных......................434 Агент связывания и повторения..........................437 Потребители данных: HTML-элементы.......................438 Элементы DIV и Span....................................438 Элемент Input..........................................439 Элемент Text Area......................................440 Элемент Marquee........................................440 Элемент Select.........................................441 Элемент IMG............................................442 Элемент Anchor.........................................442 Элемент Button.........................................443 Элемент Label..........................................443 Элементы Object и Applet...............................443 Элементы Frame и IFrame................................444 Элемент Table..........................................445 Построение базовых страниц с помощью связывания данных...448 Связывание текущей записи..............................448 Связывание таблицы с повторением...................... 450 Связывание таблицы с разбиением........................453 Написание сценариев с использованием связывания данных...455 Версия набора записей ADO..............................455 События сценариев......................................457
488Содержание ДОПОЛНИТЕЛЬНЫЕ ЭЛЕМЕНТЫ...........463 Обновление данных................463 Свойство recordNumber............464 Изменение атрибутов связывания...467 ПРИЛОЖЕНИЕ А. СЛОВАРЬ АНГЛИЙСКИХ ТЕХНИЧЕСКИХ ТЕРМИНОВ......................... 469 ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ........... 473 ОПИСАНИЕ КОМПАКТ-ДИСКА.............475