This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Информация о курсе Базовый курс веб-технологий предназначен для освоения основ HTML, CSS и Javascript. Не описывая всех возможностей, заложенных в эти языки, курс охватывает необходимый и достаточный базис для построения эффективных HTML-документов в соответствии с действующими стандартами. Курс состоит из набора лекций и лабораторных работ. Лекции содержат как теоретические сведения, так и описания конкретных приёмов, сопровождаемые примерами и упражнениями. Предварительные знания Базовые навыки работы с текстовым редактором и веб-браузером, знакомство с Интернет. Для разделов, касающихся Javascript, необходимо представления о языках программирования, желательно - об объектно-ориентированном программировании.
Лекции 1. Обзор HTML и CSS Назначение языка HTML. Стандарт HTML и спецификация XHTML. Структура документа HTML. Назначение языка CSS. 2. Текстовые элементы HTML Параграфы, заголовки, элементы логического и физического форматирования текста. Списки, гиперссылки. 3. Знакомство с HTML и CSS Цель. Практически изучить структуру HTML-документа, научиться подключать таблицы стилей и настраивать внешний вид страницы при их помощи. 4. Атрибуты стиля (CSS attributes) 5. Механизмы CSS 6. Позиционирование средствами CSS Типы позиционирования элементов в CSS и их особенности. Позиционирование на основе плавающих элементов. Приёмы центрирования и наложения элементов. 7. Создание динамического меню навигации при помощи списков и правил CSS Цель. Научиться применять элементы HTML (списки и гиперссылки), а также свойства CSS (модель отображения, псевдоклассы гиперссылок) для формирования системы навигации на веб-странице. 8. Изображения 9. Таблицы 10. Табличная и бестабличная вёрстка Макет страницы. Колонки, колонтитул, подвал. Формирование макета средствами HTMLтаблиц и правил CSS 11. Создание макета страницы средствами правил CSS Цель. Практическое освоение основных приемов верстки HTML-страницы с несколькими разделами. 12. Сценарии Javascript 13. Обработка событий при помощи сценариев Javascript Цель. Изучение приемов динамического изменения страницы в ответ на действия пользователя. 14. Динамический HTML и Объектная Модель Документа 15. Динамический HTML Цель. Изучение приёмов динамического формирования HTML-документа. 16. События. Объект event 17. HTML-формы 18. Создание формы с динамической проверкой 19. Внедрение объектов в документ HTML Возможности и недостатки динамических HTML-страниц. Применение технологий Java, Flash, SVG, AJAX, Silverlight (обзор) 20. Знакомство с Silverlight Цель. Знакомство с программой Microsoft Expression Blend. Создание анимированной Silverlight-заставки и размещение её в HTML-документе 21. Перспективы и расширения HTML
1. Лекция: Обзор HTML и CSS Назначение языка HTML. Стандарт HTML и спецификация XHTML. Структура документа HTML. Назначение языка CSS. Содержание •
Структура документа HTML
o o •
Раздел body ("тело документа")
XHTML
o • • •
Раздел head ("шапка")
Минимальный XHTML-документ
Назначение языка CSS Краткие итоги Вопросы
Начнём с того, что HyperText Markup Language (HTML) (разметки) гипертекста.
язык
определения
Под гипертекстом обычно понимается текст, содержащий ссылки на другие документы. Кроме того, гипертекст на веб-страницах, как правило, содержит форматирование (разнообразные начертания, размеры, цвета и выравнивания символов, а также графические элементы и таблицы). Разметка - процедура внедрения в текст специальных обозначений (тэгов), которые определяют ссылки и форматирование. Например, текст, заключённый между тэгами
и
, превращается в заголовок 1-го уровня:
Заголовок
. Текст между тэгами и становится гиперссылкой на ресурс, указанный в атрибуте href тэга : Поиск. Указанный тэг имеет имя a и один атрибут с именем href и значением "http://www.bing.com/". Как видно, обозначения тэгов подобраны таким образом, чтобы их легко было отличить от обычного текста. Угловые скобки зарезервированы для выделения тэгов в гипертексте. При необходимости использовать эти символы в самом тексте их обозначают по-другому: < и > (сокращения от less than и greater than - меньше и больше). Ещё одно правило тэговой разметки, которое иллюстрируют приведённые примеры, заключается в том, что тэги могут бытьоткрывающими и закрывающими:
и
, и и т.д., причём закрывающий тэг отличается от открывающего наличием символа слэша перед именем тэга и отсутствием атрибутов. В целом структура, определяемая открывающим и парным ему закрывающим тэгами, называется элементом и имеет следующий общий вид: <имя_элемента имя_атрибута1="значение_атрибута1" имя_атрибута2="значение_атрибута2"...> Текст имя_элемента> Варианты определения элемента: •
Совокупность таких обозначений и правил их использования и образует язык разметки гипертекста HTML. Этот язык в его первоначальном варианте был предложен в 1989 году английским физиком Тимом Бернерс-Ли. В 1994 году Бернерс-Ли основал консорциум WWW - с уставной целью определить стандарты для HTML и позднее для XHTML. Его члены ответственны за создание чернового варианта стандарта, организацию его обсуждения и за внесение изменений в первоначальный вариант, учитывая замечания и предложения, поступившие от интернет-сообщества, чтобы удовлетворить пожелания большинства. В настоящее время помимо HTML и XHTML в сферу ответственности консорциума WWW (W3C) входит стандартизация любых технологий, относящихся к сети (веб-технологий). Он занимается HTTP, каскадными таблицами стилей и расширяемым языком разметки (Extensible Markup Language, XML) так же, как и связанными с ними стандартами адресации в сети. Кроме того, W3C рассматривает проекты стандартов для расширений существующих вебтехнологий. В 1990-е годы консорциумом был выпущен ряд рекомендаций, касающихся HTML. Термин "рекомендация" отличается от термина "стандарт" (стандартами занимаются государственные и международные организации по стандартизации), однако в вебиндустрии рекомендации W3C, как правило, считаются фактическими стандартами, и о них говорят как о стандартах. Выпуская рекомендацию, W3C гарантирует, что её содержимое было представлено на рассмотрение общественности и членов рабочей группы, тщательно протестировано и ратифицировано на финальной стадии. Последняя такая рекомендация появилась в 1999 году - это HTML версии 4.01. А в 2000 году Международная организация по стандартизации (ISO) приняла HTML в этой версии как международный стандарт (ISO/IEC 15445:2000).
Структура документа HTML В принципе, если в html-файле (файле с расширением html или htm) написать произвольный текст безо всякой структуры, то браузер, вероятно, нормально его отобразит (браузеры "стараются" даже неправильные html-документы отобразить по возможности верно). Упражнение. Проверьте это. Структура нужна для того, чтобы всё имело своё законное место - текст, тэги, стили, скрипты, служебная информация. На первом месте HTML-документа, согласно стандарту (здесь и далее под стандартом подразумевается действующий в настоящее время стандарт HTML 4.01), находится определение типа документа (ОТД). HTML 4.01 специфицирует набора фреймов.
три
ОТД: строгое, переходное и
ОТД
для
Существенный смысл ОТД заключается в том, чтобы указать, согласно каким правилам написан HTML-документ. В рамках стандарта HTML 4.01 возможны вариации:
документ может быть написан в строгом соответствии с рекомендациями стандарта (которые предписывают отказываться от ряда элементов и атрибутов, унаследованных от предыдущих версий HTML и пользоваться вместо этого новыми, оптимизированными средствами); документ может содержать некоторые нерекомендованные элементы и атрибуты, не нарушая в остальном правил стандарта - в этом случае он будет соответствовать переходному ОТД; документ, определяющийся как структура фреймов, существенно отличается от обычного HTML-документа, и поэтому для него разработано специальное ОТД.
Вставляя ОТД в HTML-документ, следует ввести в его начало следующий текст: Строгое ОТД: Переходное ОТД: ОТД для набора фреймов: На практике наиболее широко используется переходное ОТД: фреймами вебразработчики пользуются всё реже, а следовать строгому ОТД труднее, чем переходному (без каких-либо преимуществ взамен). Если вообще опустить ОТД, то браузер сам сделает предположение о том, согласно каким правилам отображать документ. Непосредственно за ОТД должен следовать единственный в документе элемент наивысшего (корневого) уровня - элемент html (директива !DOCTYPE элементом не считается):
Раздел head ("шапка") Проще всего ответить на вопрос, что должно размещаться в разделе head, таким образом: там размещается всё, что не входит в тело документа, но необходимо для его правильного отображения. Тело документа - такие вполне зримые элементы как абзацы с текстом, списки, изображения и таблицы. Шапка документа - его заголовок, метаданные (информация о самом документе, а не о его содержимом), стили, скрипты. Пример минимального раздела head: Заголовок документа Элемент title - единственный обязательный элемент раздела head.
Метаданные могут включать в себя информацию об авторах, ключевых словах документа и т.п., например: <meta name="Authors" content="Alexander Kudryashev & Pavel Svetashkov" /> Эти данные не видит пользователь, анализировать поисковые роботы.
просматривающий
страницу,
но
могут
О стилях и скриптах речь пойдёт подробно в последующих лекциях.
Раздел body ("тело документа") Здесь размещается основное содержимое документа. Выглядит это, например, так:
Hello, World!
Таким образом, документ, оформленный по стандарту ISO HTML 4.01, должен содержать ОТД, шапку документа с заголовком и тело документа (возможно, пустое). Всё содержимое документа упаковывается в подходящие HTML-элементы (абзацы, списки, таблицы, секции и т.п.) и размещается в теле документа, т.е. в разделеbody. Пример пустого, но корректного документа HTML 4.01 Transitional:
XHTML Во всех предыдущих примерах (и в большинстве последующих) все HTML-элементы имеют как открывающий, так и закрывающий тэги. Однако стандарт HTML 4.01 допускает и упрощённую разметку: во многих случаях закрывающие тэги не необходимы, поскольку последующий открывающий тэг автоматически закрывает предыдущий. Существует ещё целый ряд допущений со стороны стандарта HTML, сокращающих написание кода для удобства разработчика. Значения атрибутов можно вводить без кавычек; некоторые атрибуты вовсе можно указывать без значений. Но все эти допущения совершенно неприемлемы в рамках другого стандарта - XHTML (где X означает Extended - расширенный). Стандарт XHTML 1.0 появился в 2000 году, и долгое время официальная позиция W3C заключалась в том, что будущее HTML - это именно XHTML, и развиваться будет только этот стандарт. В настоящее время эта позиция изменилась: готовится HTML 5, а последнее достижение в развитии XHTML - стандарт 1.1 - был признан излишне строгим и в целом не принят сообществом разработчиков. Разница между HTML и XHTML происходит из невозможности дать однозначный ответ на вопрос: "Что важнее - удобство веб-разработчика или формальная строгость?". В процессе разработки стандарта консорциум WWW осознал, что HTML не может быть расширен в достаточной мере, чтобы справиться с таким материалом, как химические
формулы, музыкальная нотация или математические выражения - для этого нужны другие языки разметки. Отвечая на эти потребности, W3C разработал стандарт расширяемого языка разметки XML, в котором описываются принципы построения других языков разметки. XML, в отличие от HTML, определяет не разметку для какого-либо конкретного применения, а формальные правила разметки для любых целей. XML-совместимые языки несут информацию, которая в дальнейшем может быть проанализирована, обработана, отображена единым образом - вот почему нужна строгость определения элементов разметки. В эту новую языковую семью, по замыслу её создателей, должен был войти и преобразованный HTML, названный XHTML. Но строгость неудобна, а браузеры прощают ошибки разработчиков. По этим причинам, вероятно, ещё очень долго не произойдёт всеобщий отказ от HTML в пользу XHTML - то, что в своё время провозглашал целью консорциум WWW. Тем не менее, в данном учебном курсе весь материал даётся в виде, отвечающем требованиям XHTML. Нарушения единообразия - довольно сомнительное удобство, и мы не рекомендуем ради них игнорировать стандарт XHTML. В основном XHTML 1.0 - это тот же HTML 4.01, за следующими исключениями. 1. Элементы должны вкладываться корректно. Если один элемент содержится в другом, завершающий тег внутреннего элемента должен появиться перед завершающим тегом внешнего. 2. Каждый тег, содержащий другой тег или другое содержимое, должен иметь закрывающий тег, явно выписанный с учётом правил вложенности тегов. Отсутствующий закрывающий тег - это ошибка, из-за которой документ будет признан несоответствующим стандарту. 3. Пустые элементы, которые в принципе не могут содержать вложенных элементов (например, ), должны тоже иметь закрывающие теги, либо быть оформленными как самозакрывающиеся: . 4. XHTML определяет все теги и атрибуты, заимствованные из HTML, используя строчные буквы. Записанные заглавными буквами имена тегов и атрибутов не являются допустимыми тегами и атрибутами XHTML. 5. XHTML требует, чтобы все значения атрибутов (включая числовые) были заключены в кавычки. 6. В HTML имеется небольшое количество атрибутов без значений, присутствие которых модифицирует поведение элементов, например: . В XHTML значение обязательно для каждого атрибута. Атрибуты без значений должны использовать в качестве таковых собственные имена: .
Минимальный XHTML-документ Заголовок Документ начинается с указания на то, что он основан на стандарте XML 1.0 и использует восьмибитовое представление (UTF-8) Unicode для записи его содержимого
и разметки. Затем в предложении объявляется, что документ следует правилам разметки, определенным в переходном ОТД XHTML 1.0, которое позволяет употреблять в документе практически любые элементы HTML 4.01. Существуют также строгое ОТД XHTML и ОТД структуры фреймов XHTML. Содержимое документа начинается с тега , который содержит атрибут xmlns, объявляющий, что пространство XHTML будет применяться по умолчанию для всего документа. Для обычного HTML-документа указание пространства имён не имеет особого смысла, поскольку набор используемых элементов ограничен стандартом. Но для XMLдокумента (разновидностью которого является XHTML-документ), это - необходимость, поскольку его призвание - в универсальности описания структур и одно из применений - в сочетании разнородных структур. Например, W3C описывает возможность соединения в одном документе разметки XHTML, MathML (разметки математических формул) и SVG (разметки векторной графики) см. http://www.w3.org/TR/XHTMLplusMathMLplusSVG/. В таком документе могут присутствовать элементы гипертекста (body, div, p), формул (math, mrow, mfrac), графики (rect, circle, ellipse) и т.д. Очевидно, что было бы неосмотрительно смешивать эти элементы в одном документе, не имея какого-либо различающего признака, указывающего на источник определения каждого из них (тем более, что, в принципе, не исключено совпадение имён в разных источниках). Таким источником и является пространство имён, имеющее смысл префикса, явно или неявно добавляемого к именам элементов. В частности, атрибут xmlns="http://www.w3.org/1999/xhtml", который необходимо указывать для элемента htmlсогласно спецификации XHTML 1.0, означает, что все элементы, определённые в документе, относятся к пространству имён http://www.w3.org/1999/xhtml. Данное значение похоже на адрес веб-страницы, однако на самом деле оно всего лишь определяет уникальный идентификатор, дающий представление о том, какой организацией, в каком году и под каким названием определён тип документа и его элементы. XHTML-документ можно сохранить с расширением xhtml или xml и открыть в браузере. Однако браузер Microsoft Internet Explorer (по крайней мере, IE8) не поддерживает XHTML как тип содержимого и не сможет открыть этот файл! Дело не только в том, согласно каким правилам мы написали документ и какие директивы DOCTYPE в него включили. Браузер - программа довольно широкого применения: она может читать текст, HTML, XHTML, ряд графических форматов и т.д. Приступая к чтению файла, браузер должен определиться, какого типа это содержимое. Когда мы открываем локальный файл, то на тип содержимого указывает его расширение (и ключи реестра); когда же загружаем его с веб-сервера(где расширение файла в запросе совершенно не обязательно должно быть указано), то сервер, отвечая на запрос браузера, включает в ответ заголовок видаcontent-type: text/html или text/xml и т.п. В результате браузер всегда информирован о типе содержимого до того, как он начинает читать это содержимое, и он запускает свою подпрограмму - парсер (анализатор текста), специализированную на чтении именно данного типа содержимого. Дело в том, что в большинстве случаев XHTML-документы читает парсер HTML - для него это не представляет затруднений, ведь XHTML, добавляя к HTML строгости, вместе с этим добавляет совсем немного того, чего нет в HTML (например, самозакрывающиеся теги и значения атрибутов, совпадающие с их именами). Почему? Потому что документы XHTML обычно передаются как text/html. А почему они передаются таким образом? Потому что, если передавать XHTML-документы как text/xml, то браузер IE (самый популярный в настоящее время) будет совершенно отказываться их читать. Впрочем, существует трюк, предложенный W3C, позволяющий обойти эту трудность, но
его применение затрагивает технологию XSLT, далеко выходящую за рамки данного курса. Резюме таково: документы, которые мы пишем с соблюдением более строгих правил XHTML, браузеры всё равно читают как HTML (это легко заметить, искусственно внеся в документ ошибки, нарушающие одно из вышеперечисленных правил). Тем не менее, именно XHTML предпочтителен для изучения, поскольку он устроен более правильно, и его правила (правила XML) применяются в области, значительно более широкой, чем технологии веб-разработки. Упражнения. Создайте XHTML-документ минимальной структуры и добавьте в него какой-либо элемент, например, абзац. Сохраните файл с расширением xhtml и откройте сначала в IE, а затем в каком-либо браузере, поддерживающем XHTML как тип документа (фактически, это любой другой современный популярный браузер). Сравните результаты. Внесите в созданный документ ошибку, нарушающую правила XHTML (например, добавьте атрибут со значением без кавычек). Откройте документ в поддерживающем стандарты браузере - вместо документа там должно отобразиться сообщение об ошибке разбора. Измените расширение файла на htm (оставив ошибку в документе). Откройте документ в любом браузере.
Назначение языка CSS Как было показано в предыдущих разделах, типичный HTML-документ представляет собой набор элементов, содержащих другие элементы либо текст. HTML-элементы могут иметь атрибуты - большинство атрибутов отвечают за такие визуальные характеристики элемента как цвет (color), отступ (margin), рамка (border), размеры (width, height) и т.п. Другая большая группа атрибутов определяют реакции элементов на такие события как щелчок мышью (onclick), нажатие клавиши (onkeydown) и т.д. Ряд атрибутов отвечают за информационное содержание, например, гиперссылка (href) или значение в элементе ввода (value). Таким образом, атрибуты элементов можно принципиально разделить на группы по критерию: "Что определяет атрибут?" - представление, поведение или содержание (существуют и другие, не попадающие в эти группы, атрибуты). Нетрудно заметить, что применение атрибутов представления на практике обычно имеет массовый характер, в отличие от атрибутов поведения или содержания. Иными словами, имея в документе множество элементов "абзац" (p), веб-дизайнер наверняка будет применять одно и то же форматирование ко многим из них. То же можно сказать и об изображениях, и о таблицах, и об элементах форм - вообще, в основе хорошего дизайна лежит разумное единообразие. Достичь единого представления для множества элементов посредством задания соответствующих значений атрибутов каждого из них в принципе возможно, но обременительно - как по объёму требуемых для этого усилий, так и по громоздкости результирующего кода. Так, например, при отнюдь не вычурном дизайне может потребоваться указать для абзацев цвет фона, гарнитуру, размер и цвет шрифта:
Несколько абзацев текста синего цвета, написанный шрифтом кеглем 14 пунктов на светло-зелёном фоне.
Стиль всех абзацев одинаковый.
Однако встроенные стили приходится повторять для каждого из
14pt;
background:
гарнитуры Verdana
14pt;
background:
14pt;
background:
них.
Листинг 1.1. Встроенные стили (html, txt)
Отступы, рамки, межсимвольное расстояние, фоновые изображения и многое другое также может быть включено в значение атрибута style (определяя таким образом встроенный стиль элемента p), однако это весьма нерационально - по крайней мере, по одной причине: одни те же значения указываются многократно вместо того, чтобы сделать это единожды. Если бы HTML-документы строились таким образом, они представляли бы собой тяжёлую структуру из хорошо перемешанных определений содержания и представления. Упражнение. Замените цвет текста (color) на чёрный (black) в каждом абзаце примера. Поэтому для определения атрибутов представления HTML-элементов создан специальный язык - Cascading Style Sheets (каскадные таблицы стилей), позволяющий отделить представление от содержания HTML-документа и определить представление либо в отдельном файле, либо в отдельном элементе styleв "шапке" HTML-документа. Рекомендация W3C, выпущенная в 1998 году, определяет CSS 2, который поддерживается всеми современными браузерами. Как и любой хорошо спроектированный язык, CSS позволяет давать короткий исчерпывающий ответ на простые вопросы, регулярно возникающие перед вебдизайнерами. Например, ответ на простой вопрос: "Какими должны быть рамки таблиц в документе?" можно сформулировать так: table { border: 1px solid black; } Данное правило CSS означает: "таблицы везде (где не указано иное) должны иметь сплошную рамку чёрного цвета толщиной в 1 пиксел". <style type="text/css"> p { color: Blue; font-family: Verdana; font-size: 14pt;
Ещё несколько абзацев текста синего цвета, написанный шрифтом гарнитуры Verdana кеглем 14 пунктов на светло-зелёном фоне.
На этот раз стиль абзацев определён при помощи правила CSS, применённого к элементу p.
Поэтому все абзацы выглядят одинаково - при существенно меньшем количестве работы по написанию и, главное, переделке стилей.
Листинг 1.2. Каскадный стиль (html, txt)
Упражнение. Замените цвет текста (color) на чёрный (black) в стиле абзаца. Сравните трудоёмкость этого изменения с предыдущим упражнением.
Краткие итоги Для разметки веб-страниц создан язык HTML, стандартизованный консорциумом WWW. Разметка состоит из элементов с атрибутами; границами элементов являются открывающие и закрывающие тэги. Для разметки произвольного содержимого (графики, формул и т.п.) консорциумом WWW разработан язык XML, и HTML приведён в соответствие с XML спецификацией XHTML, которая отличается большей строгостью и систематичностью правил. Отделение представления документа от его содержимого достигается при помощи языка CSS, определяющего правила стилей для элементов разметки.
Вопросы • • • • • • • • • •
Что означают аббревиатуры HTML и CSS? Что такое тэг, элемент, атрибут? Какое содержимое может иметь элемент? Какая последняя версия стандарта HTML? Кем и когда она создана? В чём отличие строгого и переходного ОТД? Какие элементы обязательно должны входить в документ HTML? В чём принципиальное отличие XHTML от HTML? Какие правила отличают XHTML от HTML? Для чего указывается пространство имён в XML-документе? В чём назначение CSS?
2. Лекция: Текстовые элементы HTML Параграфы, заголовки, элементы логического и физического форматирования текста. Списки, гиперссылки Содержание •
Заголовки и абзацы
o o •
Управление разбивкой текста на строки (br, nobr, pre) Секция (div - division) Список (ol - ordered list, ul - unordered list) Таблица (table)
Якорь. Специальные символы
o o •
Выделения (strong, em - emphasis, span)
Секция, список
o o o •
Абзац (p - paragraph)
Логическое и физическое форматирование. Разбивка на строки
o o •
Заголовок (h1..h6 - header 1...6)
Якорь (a - anchor) Специальные символы
Вопросы
Разобравшись со структурой HTML-документа, логично перейти к изучению того, как наполнять документ содержанием. В первую очередь, это текст. Как уже говорилось, текст в html-файл можно поместить и безо всякой структуры. Однако, если соблюдать правила, то следует выбрать для текста подходящий контейнер и разместить его в элементе body. Рассмотрим наиболее важные текстовые контейнеры.
Заголовки и абзацы Заголовок (h1..h6 - header 1...6) Заголовки имеют большое значение. Для пользователя они создают ориентиры в документе и проясняют его структуру, а поисковые серверы используют заголовки, чтобы индексировать структуру и содержание веб-страниц. Элемент h1 определяет наиболее крупный заголовок; h6 - наименее крупный. Заголовки h1 должны использоваться как главные заголовки, сопровождаемые заголовками h2, затем менее важными заголовками h3, и так далее. Обычно авторы применяют h1 для названия документа, h2 для названий разделов и т.д.
Рис. 2.1. Заголовки уровней 1-6 Обратите внимание, что каждый заголовок располагается на новой строке и имеет вертикальный отступ от соседних элементов. Первое свидетельствует о том, что заголовок - элемент блочный, т.е. всегда вызывает разрыв строки до и после себя. Второе означает, что предопределённые значения отступов для этого элемента отличны от нуля (как их можно регулировать, далее будет рассматриваться).
Абзац (p - paragraph) Служит для смысловой разбивки текста. Браузеры, отображая содержимое этого элемента (также блочного), обычно вставляют перед ним вертикальный отступ, немного больший по высоте, чем одна строка - таким образом абзацы отделяются друг от друга по умолчанию. При помощи стилей можно достичь и более привычного, "книжного" вида - горизонтального отступа первой строки каждого абзаца. Возможны и другие варианты. p { text-indent: 2.5em; margin-top: 0.2em; margin-bottom: 0.2em; } ...
По умолчанию браузер визуально отделяет абзацы друг от друга вертикальным отступом, что эквивалентно установке свойств margin-top и margin-bottom в некоторое отличное от нуля значение.
В данном примере этим свойствам задано небольшое значение (0.2em, т.е.
Буквица - ещё один эффект, применяемый для визуального выделения начала абзаца. В CSS он может быть достигнут путём применения специфического стиля к первой букве абзаца.
Первой букве абзаца соответствует селектор псевдоэлемента p:first-letter. Для этого псевдоэлемента в данном примере назначена высота 2em и красный полужирный шрифт.
Листинг 2.3. Разделение абзацев выделением первой буквы (html, txt)
Рис. 2.3. Разделение абзацев выделением первой буквы Упражнение. Попробуйте переформатировать текст одного из абзацев путём вставки в него пробелов для увеличения отступа и разбивки на строки путём нажатия клавиши Enter. Убедитесь, что форматирование HTML-кода такими средствами никак не влияет на отображение документа браузером, т.е. для разбивки текста на абзацы необходим элемент p, а для их разделения - один из рассматриваемых в данном примере способов. Как видно из примеров, в теле HTML-документа расположены несколько абзацев, и никакого форматирования. Однако форматирование к абзацам всё же применяется, поскольку к HTML-документу подключена таблица стилей. Это достигается путём включения в "шапку" HTML-документа следующей ссылки: Подробно эта директива и другие способы подключения таблиц стилей описаны в лекции "Каскадные стили". Пока достаточно понять, что таблица стилей "Style.css" учитывается браузером при форматировании HTML-документа. В таблице стилей содержится определение стиля элемента p (т.е. абзаца). Об определениях стилей также речь пойдёт позже, однако на текущий момент вполне достаточно понимания того, что свойства, указанные в стиле для элемента p, будут применены ко всем абзацам документа. Остановимся подробно на этих свойствах: • •
margin-top Верхнее поле, т.е. расстояние от верхней границы элемента (в данном случае, абзаца) до других элементов. margin-bottom Нижнее поле, т.е. расстояние от нижней границы элемента до
других элементов. Единица измерения, использованная в данном примере для задания высоты поля - em, что означает "равна высоте шрифта" (em - латинская буква m, напечатанная шрифтом Cicero - стандартная единица измерения в полиграфии) . Соответственно, 0.5em означает "равно половине высоты шрифта". Упражнение. Попробуйте уменьшать и увеличивать значения margin-top и margin-bottom, наблюдая за результатом. Затем уберите совсем объявления полей. В результате поля увеличатся! Это происходит потому, что браузеры используют по умолчанию не нулевые значения полей, а такие, как вы увидели, проделав это упражнение.
Логическое и физическое форматирование. Разбивка на строки Выделения (strong, em - emphasis, span) Позволяют акцентировать отдельные фрагменты текста (как правило, слова и фразы) при помощи форматирования. Элементstrong по умолчанию делает вложенный текст полужирным, em - курсивом, но при помощи стилей такое поведение легко переопределяется. Элемент span по умолчанию никак не влияет на вложенный в него текст - к нему всегда нужно применять стиль. strong { color: Red; } .accent { background: #BFFFBF; color: Blue; font-weight: bold; } ...
Элемент strong по умолчанию делает вложенный текст полужирным, em - <em> курсивом, но при помощи стилей такое поведение <strong>легко переопределяется. Элемент span по умолчанию никак не влияет на вложенный в него текст к нему всегда нужно <span class="accent">применять стиль.
Рис. 2.4. Переопределение поведения элемена strong - выделение цветом Очевидно, одних и тех же результатов можно добиться, назначая стили любому из контейнеров em, strong, span (и многих других). Однако, хотя и на экране результат будет одинаков, с точки зрения программного анализатора структуры документа (каковым является, например, поисковый робот), разница большая. Ряд HTMLэлементов используются для логического форматирования документа (в отличие от физического) и имеют следующий смысл: Таблица 2.1. Элемент Описание abbr Указывает, что заключённый в нём текст является сокращением acronym Указывает, что заключённый в нём текст является акронимом (сокращением, составленным из заглавных букв) address Определяет контактный адрес автора документа - например, e-mail blockquote Определяет блочную цитату (длинную выдержку из другого документа), которая отображается, как правило, со специальным отступом и курсивом cite Указывает, что заключённый в нём текст является библиографической ссылкой code Используется для показа программного кода (как правило, отображается моноширинным шрифтом) del Указывает, что заключённый в нём текст автор исключил из текущей редакции документа - отображается, как правило, зачёркнутым текстом dfn Употребляется для выделения термина, впервые появившегося в тексте (как правило, отображается курсивом) em Логическое ударение (как правило, отображается курсивом) ins
Указывает, что заключённый в нём текст автор добавил в текущую редакцию документа - отображается, как правило, подчёркнутым текстом
kbd
Используется для показа текста, который пользователь должен вводить с клавиатуры (как правило, отображается моноширинным шрифтом)
Ещё более сильное логическое ударение (как правило, отображается полужирным шрифтом)
В элементы сокращений (abbr и acronym) обычно включают атрибут title, определяющий расшифровку сокращения. Значение атрибута title появляется на экране только тогда, когда на элемент наводится указатель. Пример определения сокращения при помощи элемента abbr: WWW Упражнения. Добавьте к примеру цитату (используя элемент cite) и фрагмент кода (code). Добавьте к примеру оба вида сокращений (abbr и acronym) и пронаблюдайте отображение title. Другая группа текстовых контейнеров определяет физическое форматирование текста: Таблица 2.2. Элемент Описание b Определяет полужирный текст big Определяет крупный текст i Определяет текст курсивом small
Определяет мелкий текст
sub
Определяет текст – нижний индекс
sup
Определяет текст – верхний индекс
tt
Определяет текст телетайпа (моноширинный)
Как видите, одних и тех же визуальных результатов можно добиться при помощи разных элементов. Делая выбор, следует руководствоваться не только тем, как элемент будет отображаться на экране, но и тем, как, например, произнёс бы его синтезатор речи или как бы мог его интерпретировать поисковый робот. В одних случаях предпочтение отдаётся логическому форматированию, в других - физическому.
полужирный текст
курсив
подчёркнутый текст
моноширинный текст
на 1 пункт крупнее
<small>на 1 пункт мельче
Верхний и нижний индексы: c<sub>0 + c<sub>2x<sup>2
c<sub>1x+
Листинг 2.5. Элементы физического форматирования текста (html, txt)
Рис. 2.5. Элементы физического форматирования текста Упражнение. Пользуясь элементами физического форматирования текста, запишите несколько химических формул и физических уравнений.
Управление разбивкой текста на строки (br, nobr, pre) Как уже говорилось, разбивка на строки кода HTML-разметки не влечёт разбивки браузером на строки документа. Один из способов разрыва строки - применение блочного элемента, например, абзаца. Другой способ (исключающий добавление дополнительных отступов) - это вставка в текст элемента разрыва строки br. Существует и элемент nobr (нестандартный), имеющий противоположное назначение: текст, заключённый в него, не будет разбит браузером на строки, независимо от количества символов. Untitled Page
<nobr>Этот очень длинный абзац вообще не будет разбит на строки пользуйтесь горизонтальной прокруткой. Curabitur vitae tincidunt lorem...
Листинг 2.6. элементов HTML для разбивки текста на строки (html, txt)
Рис. 2.6. Применение элементов HTML для разбивки текста на строки Пример для элемента pre
Далее приведён листинг программного кода, помещённый в HTML-элемент pre, и он отображается с теми же отступами, как в Visual Studio:
<pre> oDigits.onmousedown = oSigns.onmousedown = function(e) { var elem = null; if (e) elem = e.target; else elem = window.event.srcElement; elem.style.color = 'red'; } oDigits.onmouseup = oSigns.onmouseup = function(e) { var elem = null; if (e) elem = e.target; else elem = window.event.srcElement; elem.style.color = ''; } Листинг 2.7. Пример для элемента pre (html, txt)
Элемент pre (преформатированный вывод) выделяет в разметке фрагмент, который браузер должен отобразить "как есть", теми же символами и с тем же разбиением на строки, включая все пробелы. Текст внутри элемента pre может содержать физическую и логическую разметку, а также якоря, изображения и горизонтальные линейки. Весь текст в элементе будет отображен моноширинным шрифтом.
Чаще всего преформатированный вывод используется для представления исходных кодов программ, как в следующем примере.
Рис. 2.7. Пример для элемента pre
Секция, список Секция (div - division) Не несёт никакой логической нагрузки и используется, как правило, в качестве строительного элемента при вёрстке страницы. Здесь важно провести следующее разделение между всеми элементами тела HTML-документа: строчные (inline) элементы могут занимать часть строки, а блочные (block) всегда занимают целое число строк. Большинство HTML-элементов - строчные; к блочным относятся заголовок, абзац, секция, список и таблица (а также некоторые другие элементы, которые будут рассмотрены особо). Таким образом, с точки зрения представления на экране секция ничем не отличается от абзаца. Главное различие состоит в том, что в абзац нельзя поместить другой абзац (и вообще блочный элемент), а в секцию разрешается помещать любые другие элементы, включая секции. Поэтому в качестве универсального контейнера обычно используется именно секция. При проектировании макета веб-страницы обычно мыслят блоками: блок колонтитула, блок меню, блок основного содержимого и т.д. Как правило, каждый
блок реализуется при помощи секции либо списка. Подробно использование блоков рассмотрено в лекциях "Позиционирование" и "Табличная и бестабличная вёрстка"
Список (ol - ordered list, ul - unordered list) Используется для нумерации или маркировки последовательности элементов. В следующем примере показаны основные приёмы разметки списков. ol { list-style-type: upper-roman; } ...
Первый список:
Пункт
Ещё один пункт
Последний пункт
Вложенный список:
Пункт
Ещё один пункт
Последний пункт
Листинг 2.8. Списки и их оформление стилями (html, txt)
Рис. 2.8. Вложенный список ul li { list-style-type: disc;
Листинг 2.9. Изображение в качестве маркера (html, txt)
Рис. 2.9. Изображение в качестве маркера Как видно из примера, пункты в списке должны обрамляться элементами li (list item элемент списка), которые, в свою очередь, погружаются в элемент ol или ul. Специфические свойства элементов ol и ul: •
list-style-type Указывает вид маркера или номера. Упражнение. В примере "Выбор маркера" попробуйте использовать следующие значения этого свойства:
•
o circle o disc o decimal o square o lower-alpha o lower-roman o upper-alpha o upper-roman o none list-style-image Позволяет вместо маркера из стандартного набора использовать любое изображение. При этом необходимо учитывать, что размер изображения должен быть подходящим (в CSS нет средств для его изменения), а на тот случай, если загрузка изображений в браузере отключена, рекомендуется указывать и какое-либо значение свойства list-style-type.
list-style-position Предоставляет выбор снаружи (outside) или внутри текста (inside).
способа
размещения
маркера
Специфический атрибут элемента ol - start, указывающий начальный номер списка, например: . Большинство общих свойств CSS также применимо к спискам - как к элементу ol или ul (списку в целом), так и к элементу li (отдельным элементам списка). Упражнение. Задайте списку: а) рамки (сначала для списка в целом, затем для его пунктов); б) фоновый цвет; в) отступ слева. Пользуясь псевдоселектором first-letter, измените цвет и размер начальных букв пунктов списка. •
list-style Соединяет объявления свойств list-style-type , list-styleimage и list-style-position в одном сокращённом объявлении: list-style: [list-style-type] [list-style-image] [list-style-position] Например: list-style: square inside;
Таблица (table) Назначение этого элемента очевидно, и он является самым сложным по структуре и возможностям форматирования. Подробно он рассмотрен в отдельной лекции.
Якорь. Специальные символы Якорь (a - anchor) Служит для определения гиперссылки либо точки назначения ("якоря") гиперссылки. В документе HTML гиперссылкой может являться фрагмент текста или изображение, помещённые в элемент a. Браузер, отображая элемент a, по умолчанию (т.е. если не задать других правил) обычно выделяет текст синим цветом и подчёркиванием, а также отображает курсор в виде указателя, когда он проходит над ссылкой - будь то текст или изображение. При нажатии на гиперссылку она активизируется, и браузер выполняет переход по URL (универсальному локатору ресурса), указанному в атрибуте hrefэлемента a. Вот типичный пример текстовой гиперссылки: Интернет Университет Информационных Технологий URL может указывать как на веб-страницу (документ HTML), так и на содержимое какого-либо другого типа. Браузеры умеют отображать, кроме HTML-документов, текстовые файлы и файлы изображений некоторых типов (jpg, png, gif). Другое содержимое (аудио, видео, документы Word и Acrobat, архивы) будет загружено браузером как файл и сохранено на компьютере пользователя. Впрочем, к браузеру могут быть подключены дополнительные программы (плагины - plugins), открывающие различное медиа-содержимое непосредственно в окне браузера. К популярным плагинам такого рода можно отнести Adobe Flash Player, Apple QuickTime, Microsoft Silverlight и плагин Adobe Reader. Составные части URL имеют следующий смысл (здесь показаны только наиболее простые, необходимые элементы):
протокол://сервер/файл#якорь Элемент сервер определяет, к какому компьютеру отправляется запрос: любой компьютер имеет свой уникальный числовой адрес в рамках сети (IP-адрес), а многие компьютеры-сервера (компьютеры, предназначенные для обработки запросов) имеют также доменное имя, такое как ya.ru. В URL указывается либо доменное имя, либо IPадрес. Элемент протокол определяет, какая программа на сервере будет обрабатывать запрос - веб-сервер (такой как Apache, IIS, Tomcat и др.), служба FTP или другая. Также от этого зависит, по какому протоколу будут передаваться данные от сервера клиенту (браузеру). Если указан протокол file, то браузер прочитает файл с локального компьютера. Псевдопротокол javascript при активизации ссылки вызовет указанную функцию, например: Назад . При активизации ссылки с псевдопротоколом mailto откроется почтовый клиент и создастся письмо с указанным адресом, например: Написать письмо. Элемент файл определяет путь к файлу на сервере - к документу HTML, изображению, архиву или, может быть, к серверной странице (php, aspx, jsp и т.п.), которая по запросу генерирует HTML-документ. Разумеется, разновидностей серверных программ и типов документов довольно много, и полное их описание не является задачей данной лекции. И, наконец, якорь означает идентификатор элемента внутри документа, на который направлена ссылка. Если якорь в URL не указан, то документ открывается сначала, иначе - в верхней строке окна оказывается начало некоторого HTML-элемента, имеющего указанный идентификатор (т.е. атрибут id или name). Впрочем, если высота содержимого от якоря до конца документа меньше высоты окна браузера, то, естественно, якорь окажется не вверху окна, а ниже. <style type="text/css"> a:link { color: #33ccff; } a:visited { color: #cecece; } a:hover { color: #336666; } a:active { color: #339999; } …
id="start"> href="#div2">К секции div2 href="#end">В конец документа href="http://ya.ru">На Яндекс
<strong>Это текст в секции div1 - Lorem ipsum dolor sit amet... Lorem ipsum dolor sit amet…
id="end"> href="#start">В начало документа href="#div1">К секции div1 href="http://ya.ru">На Яндекс
Листинг 2.10. Гиперссылки и их оформление стилями (html, txt)
Рис. 2.10. Стили ссылок Упражнения. Добавьте ссылку на какой-либо локальный файл (текстовый документ, html-документ или изображение). Пример URL: file://C:\Documents and Settings\Admin\Мои документы\Мои рисунки\Image.png. Убедитесь, что ссылка работает (файл должен существовать!). Добавьте дополнительный якорь в середину секции div1 и создайте ссылку на него в начале документа. Сделайте разными стили для ссылок в секциях div1 и div2 (например, пусть у них будут разные цвета - во всех состояниях, включая visited, hover и active). Для этого дополните соответствующие CSS-правила селекторами элементов: #div1 a:link и т.д. Как видно из примера, элемент a - строчный. Что будет, если элементам a задать свойство display:block?
Специальные символы Содержащиеся в документе символы, не являющиеся при этом частью тегов, обычно отображаются браузером "как есть". Некоторые символы, однако, имеют специальное
значение и прямо не выводятся, другие же невозможно набрать со стандартной клавиатуры. Для включения специальных символов в документ требуется их кодирование: либо с помощью специальных названий, либо с помощью числовой кодировки Latin-1. В таблице 2.3 приведены названия некоторых специальных символов, а также их номера в кодировке Latin-1 Таблица 2.3. Имена и номера специальных символов Результат Описание
Вопросы 1. Для чего нужны заголовки в документе, при помощи каких элементов они создаются и как выглядят? 2. Какой элемент формирует абзац? 3. Чем отличаются логическое и физическое форматирование? Назовите несколько элементов соответствующих и поясните их значения. 4. Какие средства используются для указания разрывов строк в тексте, кроме блочных элементов? 5. Для чего обычно используется элемент div? 6. Какие способы маркировки и нумерации списков заложены в HTML? 7. Каких эффектов (касающихся маркировки) можно достичь, применяя правила CSS к элементам списка? 8. Каким образом включается гиперссылка в HTML-документ? 9. Перечислите и определите основные составные части URL. 10. Почему для специальных символов необходимы особые обозначения? Какие это обозначения?
3. Лабораторная работа: Знакомство с HTML и CSS Цель. Практически изучить структуру HTML-документа, научиться подключать таблицы стилей и настраивать внешний вид страницы при их помощи. Содержание •
Часть 1. Создание html-документа. Добавление абзацев. Назначение стилей элемента body
Часть 2. Вставка изображения, гиперссылки и элементов логического форматирования
o o o •
1. Создание каркаса документа XHTML 1.0 Transitional.
1. Вставка изображения. 2. Вставка подписи с гиперссылкой. 3. Вставка элементов логического форматирования.
Часть 3. Применение каскадных правил. Центрирование элементов, добавление границ и полей
o o o
1. Создание рамки изображения. 2. Центрирование изображения с подписью 3. Добавление рамки и фона абзацу.
Часть 1. Создание html-документа. Добавление абзацев. Назначение стилей элемента body
1. Создание каркаса документа XHTML 1.0 Transitional. На начальном этапе мы рекомендуем воспользоваться простейшим (не специализированным) текстовым редактором, который не окажет вам абсолютно никакой помощи по вводу HTML-тэгов и атрибутов - зато вы получите возможность обратить внимание на каждую деталь, что наверняка окажется полезным в дальнейшей работе. Предлагаем использовать, например, WordPad. Откройте редактор и сразу сохраните пустой еще файл под именем Lab1.htm в какую-либо папку, которую вы создали специально для лабораторных работ по данному курсу. Введите определение типа документа XHTML 1.0 Transitional, затем элемент html, а внутри него - head (с заголовком) и body - пока без содержимого. Напоминаем, что определение пустого элемента состоит из открывающего и следующего сразу за ним закрывающего тэга. Примеры этих элементов имеются в первой лекции. Советуем не копировать (на этот раз), а набрать вручную - это дает некоторую гарантию того, что вы будете помнить то, как код должен выглядеть и быстрее находить в нем ошибки (с которыми вы рано или поздно столкнетесь).
2. Ввод заголовка и абзаца текста. В теле документа (внутри элемента body) введите элемент заголовка первого уровня с произвольным текстом. Затем введите элемент абзаца - также с произвольным текстом. Изучая технику применения веб-технологий, мы в данном курсе абстрагируемся от содержания и используем, как правило, бессмысленный заполняющий текст исторически для дизайнеров это "Lorem ipsum" (см. http://www.lipsum.com). Следите за соответствием открывающих и закрывающих тэгов - каждый элемент должен либо соседствовать с другими элементами, либо быть полностью вложенным - "пересекаться" элементы не могут. Сохраните документ и откройте в браузере. Мы изучаем стандартные средства HTML, и они должны одинаково работать во всех браузерах. Однако в первую очередь обычно проверяют веб-страницы в Microsoft Internet Explorer (сокращенно IE или, как он стал называться позже, Windows Explorer), который уже много лет лидирует по популярности среди пользователей Интернет. Рекомендуем использовать последнюю
версию этого браузера (на момент написания курса - 8.0). Необходимо также делать проверку и в других браузерах - профессионалы держат под рукой все современные (и многие старые) версии всех популярных браузеров. По крайней мере, в одном из современных ориентированных на стандарты браузеров проверку делать имеет смысл (помимо IE) - дело в том, что во многом из-за своей популярности IE ведет себя наиболее нестандартно - это обусловлено стремлением его разработчиков "не обрушить Web", а поддерживать совместимость с прошлыми версиями различных спецификаций (многие из которых содержат ошибки). Если в вашей работе заголовок не выделяется форматированием из остального текста, то, вероятнее всего, где-нибудь тэг забыт или закрыт не там, где нужно.
3. Добавление таблицы каскадных стилей. Браузер отображает текст черным цветом на белом фоне, начиная с левого верхнего угла окна (точнее, как правило, делая отступ в 2 пиксела со всех сторон) во всю его ширину. Изменим этот стиль по умолчанию на собственный. Добавьте в раздел head элемент style с атрибутом type="text/css". Добавьте в него пустое правило для элемента body: <style type="text/css"> body { } Теперь по порядку назначим при помощи этого правила элементу body следующий ряд свойств: • • • • • • •
цвет фона (неяркий) толстую серую рамку большой отступ - чтобы отдалить рамку от границ окна небольшое поле - чтобы отделить текст от рамки крупный размер шрифта (например, 20px) гарнитуру Comic Sans MS отступ первой строки
Уберем рамку справа right значение none.
и
снизу,
назначив
свойствам border-bottom и border-
После каждого дополнения сохраняйте документ в редакторе (Ctrl-S), переходите в браузер (в котором ваша рабочая страница уже открыта) и нажимайте Обновить (F5), чтобы убедиться в том, что действия достигают желаемого эффекта и не нарушают прежних достижений. Удобно разделить рабочую область экрана так, чтобы одновременно видеть и редактор, и браузер. Добейтесь примерно такого вида:
Часть 2. Вставка изображения, гиперссылки и элементов логического форматирования
1. Вставка изображения. Сейчас понадобится файл с каким-либо графическим изображением типа GIF, JPG или PNG. Его геометрические размеры должны быть не слишком большими, чтобы оно аккуратно вписывалось в окно браузера. Ширина окна браузера обычно равна полной ширине экрана (если нет полосы вертикальной прокрутки) - например, 1280px. Если от ширины окна отнять удвоенный отступ нашей страницы (поскольку он делается с обеих сторон), толщину рамки и удвоенное поле, то получится максимальная ширина изображения, при которой страница будет полностью помещаться в доступную ширину окна (не требуя горизонтальной прокрутки). Кроме того, потом мы сделаем для изображению рамку с полем, что еще сократит пространство на странице. И, наконец, слишком большие изображения выглядят обычно не очень хорошо - все эти соображения приводят к заключению, что ширину изображения лучше выбирать достаточно небольшой. Если вы подобрали изображение, определите его ширину и высоту - для этого достаточно навести в Проводнике курсор на этот файл, либо открыть окно его свойств. Если не указать ширину и высоту изображения, браузер может определить их и сам, но
для этого ему нужно загрузить это изображение. Возможны ситуации, когда браузеру знать размеры изображения необходимо, но загружать само изображение не нужно здесь явное указание размеров будет полезным. Еще один полезный момент явного указания размеров в разметке заключается в том, что, компонуя страничные элементы, вы оперируете, как правило, размерами в пикселах, и наличие размеров изображения в разметке страницы помогает вам в этой задаче. Вставьте в документ (внутри элемента body, но после заголовка и абзаца) элемент img: Атрибуты элемента сообщают браузеру: • • • •
имя файла (предполагается, что он находится в той же папке, что и документ HTML); ширину изображения в пикселах; высоту; альтернативный текст - который будет показан, если показ рисунков выключен или проговорен, если просмотр выполняется при помощи синтезатора речи.
Согласно спецификации, обязательными.
атрибуты src и alt для
элемента img являются
2. Вставка подписи с гиперссылкой. Далее вставьте абзац с произвольным небольшим текстом (выполняющим функцию подписи). Внутри абзаца, после текста подписи, вставьте гиперссылку. на какую-либо Интернет-страницу, либо на локальный HTML-файл.
3. Вставка элементов логического форматирования. Добавьте заголовок второго уровня с произвольным текстом и неупорядоченный список с двумя-тремя элементами. Просмотрите результат в браузере - вероятно, в список проникли отступы первых строк, определенные ранее для всех элементов в body (ведь это свойство наследуется вложенными в контейнер элементами). Очевидно, отступы первых строк должны быть определены не для всех элементов без разбора - достаточно, чтобы их имели абзацы и заголовки: p, h1, h2 { text-indent: 40px; } Переопределите правило для отступа первой строки указанным образом. Сделаем врезку в документе - блок текста, выделенный особым форматированием - как правило, гарнитурой и начертанием. Вставьте в документ элементblockquote (цитату) с произвольным текстом из 1-2 предложений. Создайте правило для элемента blockquote, задающее для него другую гарнитуру (например,Serif) и начертание (например, italic). Вставьте в документ последний, относительно длинный, абзац. Сделайте в нем выделения при помощи элементов логического форматирования strong и span. Определите какую-либо аббревиатуру (abbr).
Элементу span назначьте атрибут class="greenspan". Добавьте правило стиля с селектором класса, делающее цвет текста в элементе этого класса зеленым и подчеркнутым: .greenspan { color:Green; text-decoration:underline; } Вот примерный результат. Обратите внимание на аббревиатуру (в данном примере "NSCE") - она может иметь точечное подчеркивание и отображает подсказку (определенную атрибутом title) при наведении указателя.
Часть 3. Применение каскадных правил. Центрирование элементов, добавление границ и полей
1. Создание рамки изображения. Добавьте стилевое правило для элемента img, включающее тонкую сплошную серую рамку и поле: img { padding: 10px; border: 1px solid #777; }
2. Центрирование изображения с подписью Поместите изображение (элемент img) и его подпись (следующий элемент p) в секцию, т.е. создайте пустой элемент div и переместите в него элементы img и p (вместе с элементом a). Теперь позиционируем секцию горизонтально по центру страницы - для этого нужно явно задать ее ширину и затем установить автоматические отступы слева и справа. Ширина секции равна ширине изображения плюс удвоенный отступ изображения плюс удвоенная толщина рамки изображения. Добавьте элементу div атрибуты class="pic" style="width:689px": стилевое правило, центрирующее секцию, имеет смысл определить для множества (класса) секций; а ширина секции привязана к ширине изображения, поэтому атрибут ширины лучше определить во встроенном стиле. Для класса pic стиль должен выглядеть следующим образом: .pic { margin-left: auto; margin-right: auto; } Проверьте, что получилось в результате.
3. Добавление рамки и фона абзацу. Создайте стилевое правило для абзаца, помещенного в секцию с классом pic: .pic p { } Селектор .pic p означает: элемент p, вложенности в элемент класса pic.
находящийся
на
произвольном
уровне
Определите в этом стилевом правиле следующие свойства: • • • • •
выравнивание текста - по центру; поле - 5 пикселов; рамка - тонкая пунктирная (dashed) серая; шрифт полужирный; фон - серый (немного темнее общего фона).
В качестве последнего штриха визуально отделим абзацы друг от друга буквицей:
4. Лекция: Атрибуты стиля (CSS attributes) Содержание •
Размеры и цвета
o o • •
Цвета
Шрифт и текст Рамки, поля, отступы, фон
o o o o • •
Единицы размеров
Рамки Поля Отступы Фон
Размещение и размер. Переполнение и обрезка Наследование. Разбивка на страницы
o o o
Наследование элементами свойств контейнеров Свойства, относящиеся к представлению документа на печатном носителе Вопросы
Таблицы стилей CSS позволяют контролировать все аспекты представления документа в браузере (или другом клиентском приложении, поддерживающим стили), включая выбор шрифта, форматирование абзацев, позиционирование элементов, многие динамические эффекты и т.д. на экране монитора и вплоть до выбора актера, "рассказывающего" документ в голосовом синтезаторе. Рассмотрим соответствующие свойства CSS.
Размеры и цвета Единицы размеров Все размеры и позиционные расположения в CSS задаются в размерных единицах. Internet Explorer и другие браузеры поддерживают как абсолютные, так и относительные единицы. Абсолютные единицы задают точный размер, например, в сантиметрах или дюймах, относительные единицы вычисляются относительно какихлибо других свойств (например, размера монитора или листа бумаги) или размеров других элементов. Допустимые абсолютные единицы: • • • • •
em – размер на основе размера шрифта (атрибута font-size). В типографии em — это единица измерения, которая представляет высоту заглавной буквы М шрифта. В веб-дизайне 1 em — это высота базового шрифта в браузере, которая обычно составляет 16 пикселов (но пользователь может изменять ее). Если эта единица применяется для определения размера шрифта, то она имеет смысл относительной величины по отношению к размеру шрифта в родительском элементе. Пример: left: 2.5em
ex – размер буквы x px – вычисляется на основе разрешения монитора или принтера % – размер относительно другого, как правило, родительского элемента. Например, ширина ячейки таблицы может быть выражена в процентах от ширины таблицы
Абсолютные единицы хороши для определения размеров элементов в версии для печати. Для отображения на экране, как правило, применяются пикселы, проценты и em. Выбирая, какую единицу измерения использовать, следует исходить из согласованности размеров элементов веб-страницы (текста, блоков, изображений и т.п.). Фактический размер элементов предсказать невозможно (это зависит от разрешения монитора, который пользователь может менять), поэтому речь идет именно о согласованности, т.е. о совместном изменении размеров элементов страницы при ее масштабировании. Если пользователь считает текст слишком мелким, то он должен иметь возможность увеличить его (и наоборот). Современные браузеры позволяют масштабировать страницу как единое целое - все элементы увеличиваются и уменьшаются пропорционально. Однако более старые браузеры (например, IE6-) не предоставляли такой возможности - вместо этого разрешалось регулировать только размер шрифта (т.е. масштабировался текст, а остальные элементы не меняли своих размеров). Существенное изменение размера шрифта текста без изменения размера контейнера этого текста, как правило, нежелательно. Здесь на помощь приходит такая единица длины как em: когда меняется размер шрифта, меняется и величина em, и размеры блоков удается согласовать таким образом со шрифтом. Измерение размера в процентах (от соответствующего размера контейнера) позволяет поддерживать согласованность другого рода - между размерами блоков и размером окна браузера. В большинстве же случаев измерение длины в пикселах - достаточно хорошее решение. div { border: 1px solid black; } #px { width: 200px; } #percent { width: 40%; } #em { width: 17em; } ...
Ширина этой секции указана в пикселах
Ширина этой секции указана в процентах
Ширина этой секции указана в em
Листинг 4.1. Использование различных единиц измерения для задания ширины (html, txt)
Упражнение. Откройте пример в новом окне браузера и измените а) масштаб страницы; б) размер шрифта; в) ширину окна. Проследите за шириной блоков.
Цвета Цвет в CSS может быть задан по имени или в виде шестнадцатеричного числа, определяющего интенсивности красного, зеленого и синего цветов (RGB схема). Стандарт HTML 4.01 определяет только 16 цветов, спецификация CSS 2.1 добавляет
еще один цвет; RGB схема позволяет задать свыше 2,000,000 цветов, от черного (#000000) до белого (#FFFFFF). Следующий пример показывает способы задания красного цвета текста: p { color: red; } /* стандартный цвет */ p { color: #f00; } /* #rgb */ p { color: #ff0000; } /* #rrggbb */ p { color: rgb(255,0,0); } /* целые в диапазоне 0 – 255 */ p { color: rgb(100%, 0.0%, 0%); } /* диапазон 0.0% - 100.0% */ Internet Explorer и некоторые другие браузеры распознают множество других именованных цветов, однако нет гарантии, что выбранный именованный цвет (в отличие от RGB схемы) поддерживается всеми браузерами.
Шрифт и текст Описание шрифта и форматирования текста состоит из целого ряда отдельных атрибутов. Многие термины здесь почерпнуты из типографской практики. Font-family (гарнитура) задает название используемого шрифта. Поскольку нет полной уверенности, что указанный шрифт установлен и доступен в любом браузере и на любой клиентской машине, разработчик может задать список альтернативных шрифтов в порядке убывания предпочтительности, разделив список запятыми. Если название шрифта содержит пробелы, оно должно быть заключено в кавычки. Пример: p {font-family: 'Times New Roman', Times, serif;} Font-size (кегль) задает размер шрифта в абсолютных или относительных единицах или относительно пользовательских предпочитаемых размеров. Пример: .p1 { font-size: small; } /* варианты: xx-small, x-small, small, medium, large, x-large, xx-large */ .p2 { font-size: larger; } /* варианты: larger, smaller */ .p3 { font-size: 10pt; } /* абсолютный размер 10 пунктов */ .p3 { font-size: 10px; } /* размер 10 пикселей. Зависит от разрешения экрана или принтера */ .p3 { font-size: 120%; } /* 120% от размера шрифта родительского элемента */
normal – обычный bold – жирный bolder – жирнее родительского lighter – светлее родительского 100 – самый светлый 200 300 400 – то же что normal 500 600 700 – то же что bold 800 900 – самый жирный
Установки жирности зависят от установленных на пользовательской машине шрифтов. Часто пользователь не может увидеть различий между близкими значениями жирности. li {font-weight: bold;} Font-variant переключает шрифт между обычным (normal) и малыми заглавными буквами (small-caps). p:first-line {font-variant: small-caps;} Line-height задает межстрочный интервал в размерных единицах или процентах межстрочного интервала родительского объекта. p {line-height: 8mm;} Перечисленные выше атрибуты могут быть объединены в составной атрибут font в следующем порядке: font-style, font-variant, font-weight, font-size, lineheight, font-family. Пример: p { font: italic normal 400 12px/14px Arial; } /* выделенные жирным значения обязательны, остальные могут быть опущены */ Эквивалентно p { font-style: italic; font-variant: normal; /* значение по умолчанию можно опустить*/ font-weight: 400; /* значение по умолчанию можно опустить*/ font-size: 12px; line-height: 14px; font-family: Arial; }
Значения font-size и font-family должны всегда присутствовать в объявлении font и быть расположены в установленном порядке. Если какое-либо из них будет пропущено, то все правило будет признано недействительным. Text-decoration допускает следующие значения: none (без декорирования), underline (подчеркнутый), overline (надчеркнутый), linethrough (перечеркнутый), а также их сочетания. li {text-decoration: underline line-through;} Text-transform задает преобразование текста следующим образом: none (нет преобразования, по умолчанию), capitalize (делает первую букву каждого слова заглавной), uppercase (все заглавные), lowercase (все строчные). h1 {text-transform: capitalize;} Text-align задает выравнивание текста внутри блока влево (left), вправо (right), по центру (center) или по ширине (justify). Text-indent определяет отступ первой строки текста от левой границы блока. p { text-align: justify; text-indent: 20px; } /* допускаются положительные и отрицательные значения */ letter-spacing регулирует расстояние между буквами. Значения: любая единица измерения CSS (обычно em или px), хотя проценты для этого свойства не работают в большинстве браузеров. Допускаются отрицательные значения. Значение normal сбрасывает letter-spacing в стандартное значение. Vertical-align устанавливает базовую линию элемента относительно базовой линии окружающего содержимого. С помощью этого свойства можно немного поднять или опустить символ относительно окружающего текста. При применении к ячейке таблицы значения top, middle, bottom и baseline управляют вертикальным размещением содержимого внутри ячейки. color устанавливает цвет текста. Значение: любое корректное значение цвета. p { font: 14px Verdana; } ...
Ко всем абзацам данного примера применено стилевое правило, устанавливающее кегль 14px и гарнитуру Verdana. Данный абзац демонстрирует эти свойства в чистом виде.
Текст этого абзаца крупнее, поскольку к нему применен встроенный стиль со значением свойства font-size:larger.
В этом абзаце увеличен межстрочный интервал путем задания свойства стиля line-height: 200%, что означает удвоенную высоту строки. Кроме того, тексту назначен красный цвет.
Эффект <span style="letter-spacing: достигается путем применения свойства letter-spacing.
3px">разреженного
текста
Пример 4.2. Свойства шрифта и текста (html, txt)
Рис. 4.1. Свойства шрифта и текста Упражнение. Попробуйте практически применить рассмотренные свойства шрифта и текста к элементам body и p в примере.
Рамки, поля, отступы, фон Рамки border-style определяет стиль для всех границ блока. Допустимые значения: solid, dotted, dashed, double, groove,ridge, inset, outset, none, и hidden. Пример: p { border-style: solid; } Отдельные стили для каждой границы задаются при помощи свойств border-bottomstyle, border-left-style, border-top-style и border-right-style, принимающих такие же значения. Пример: p { border-top-style: double; }
border-width определяет толщину для всех границ блока, указанную в любой из единиц измерения CSS, кроме процентов (как правило, в пикселах). Пример: p { border-width: 2px; } То же свойство для каждой из границ в отдельности задается при помощи одного из свойств border-top-width, border-right-width, border-bottom-width, border-leftwidth. border-color определяет цвет границ блока. Значение цвета указывается любым допустимым способом. Пример: p { border-color: Green; } Цвета отдельных границ устанавливаются при помощи свойств border-topcolor, border-right-color, border-bottom-color, border-left-color. border - сокращенное свойство, объединяющее border-width, border-style и bordercolor. Пример: p { border: 2px solid #f33; }
Поля Пустое пространство между содержимым блока и его рамкой (или если, рамки нет, то границей фона) - поле - задается свойством padding. Его размер можно указать в любых единицах измерения. Свойства padding-top, padding-right, padding-bottom и padding-left задают соответственно верхнее, правое, нижнее и левое поля. Пример: p { padding-left: 20px; } Свойство padding - сокращенное: оно позволяет задать либо сразу все поля одинаковыми (если указано одно значение), либо различные вертикальные и горизонтальные поля (если указано два значения), либо четыре различных поля, перечисленных в следующем порядке: top, right, bottom, left. Примеры: p { padding: 20px; } /* все поля равны 20 пикс */ p { padding: 5px 20px; } /* вертикальные поля равны 5 пикс, а горизонтальные 20 пикс */ p { padding: 5px 20px 5px 10px; } /* сверху 5, справа 20, снизу 5, а слева 10 пикс */
Отступы Пустое пространство между границей блока и другими блоками задается свойством margin. Оно полностью аналогично свойству padding, с тем отличием, что пространство добавляется не внутри блока, а снаружи. Пример: p { margin: 20px; }
Цвет фона блока устанавливается при помощи свойства background-color. Пример: p { background-color: #765; } body { margin: 5px; padding: 5px 10px; border: 5px solid gray; background-color: #2ae; } ...
В данном примере к элементу body применены свойства margin, padding, border и background-color. В упражнении предлагается назначить эти же свойства другим элементам страницы - абзацу, списку (и его элементам), а также изображению.
margin - отступ
padding - поле
border - рамка
background-color - цвет фона
Листинг 4.3. Поля, рамки, отступы и фон (html, txt)
Рис. 4.2. Поля, отступы, рамки и фон Упражнение. В данном примере все свойства применены к элементу body. Примените их вместо этого поочередно к остальным имеющимся в примере элементам (div, p, ul, li и т.д.). Попробуйте задавать различные значения для разных границ, разных полей и отступов.
Размещение и размер. Переполнение и обрезка top, left, right и bottom управляют положением элемента относительно контейнера: top устанавливает расстояние верхней границы элемента от верхней границы контейнера; bottom - нижней границы элемента от нижней границы контейнера и т.д. Эти свойства работают только тогда, когда элемент позиционирован абсолютно (а контейнером, относительно которого ведется отсчет, считается тот контейнер, который позиционирован абсолютно, относительно или фиксированно). Позиционированию посвящена отдельная лекция. width и height устанавливают ширину и высоту элемента. Следует иметь в виду, что фактическая высота элемента на экране - это общая сумма высоты, верхнего и нижнего
полей, верхнего и нижнего отступов, а также верхней и нижней границ. То же относится и к ширине. max-width и max-height, а также min-width и min-height определяют соответственно максимальные и минимальные размеры элемента. overflow определяет, как отображать содержимое элемента, если оно не вмещается внутри него - такое может произойти, если размеры элемента ограничены при помощи одного из описанных в данном разделе свойств. Значения: visible, hidden,scroll, auto. Значение visible позволяет показать не поместившееся содержимое вне области элемента (IE6- просто увеличивает в этом случае саму область); hidden скрывает любое содержимое за пределами отведенной ему области;scroll добавляет полосы прокрутки к элементу, auto добавляет полосы прокрутки, только когда они необходимы. div { position: absolute; border: 2px solid black; padding: 3px; } #scrolling { overflow: scroll; top: 10%; bottom: 10%; left: 0; right: 20%; } #hidden { top: 30%; left: 10%; width: 150px; height: 97px; overflow: hidden; } #visible { overflow: visible; right: 50px; top: 100px; max-width: 150px; max-height: 100px; } ...
Эта секция имеет свойство прокрутки показаны (хотя и не нужны).
стиля
overflow:
scroll
-
поэтому
полосы
Эта секция имеет свойство стиля overflow: hidden - поэтому не поместившийся в нее текст остается невидим. sed ultrices sed, malesuada pulvinar metus.
Эта секция имеет свойство стиля overflow: visible - поэтому часть текста (если его много ) может выходить за ее границы.
Листинг 4.4. Применение свойства overflow (html, txt)
Рис. 4.3. Задание позиции, размера и поведения при переполнении блоков Упражнения. Измените значение scroll на auto. Добавьте в блок, на который влияет это свойство, столько текста, чтобы появился скроллер. Чем ограничена высота блока? clip создает прямоугольное окно, которое показывает часть элемента. Значения: rect(y1, x2, y2, x1), причем вырезанная область будет представлять собой прямоугольник с левым верхним углом в (x1; y1) и левым нижним в (x2; y2). Порядок координат легко запомнить, если заметить, что x1 перенесено в конец списка. Данное свойство влияет только на абсолютно позиционированные элементы. #div1, #div2 { position: absolute; width: 320px; height: 320px; } #div1 { background-image: url(clipped.png); } #div2 { clip: rect(10px 240px 280px 20px); background-color: Blue; } ... Листинг 4.5. Обрезка абсолютно позиционированных блоков (html, txt)
Рис. 4.4. Обрезка блока Упражнение. Модифицируйте значение свойства clip так, чтобы показать а) верхнюю половину; б) левую половину; в) правую нижнюю четверть прямоугольника. display позволяет вариант отображения элемента: строчный сделать блочным (что вызывает разрыв линии над и под элементом, как у абзаца и секции), а блочный строчным (что заставит элемент отображаться на той же линии, что и окружающие элементы, как якорь или изображение). Значения: block, inline,none (всего 17 значений, большинство из которых не дают никакого эффекта в современных браузерах). Значение none заставляет элемент полностью исчезнуть со страницы. h1 { display: inline; } a { display: block; } ...
Этому заголовку назначено стилевое свойство display: inline
Листинг 4.6. Изменение варианта отображения элемента при помощи свойства display (html, txt)
Рис. 4.5. Применение свойства display Упражнение. Пронаблюдайте влияние свойства display, устанавливая его значения поочередно в block, inline и none. visibility определяет, отображает ли браузер элемент. В отличие от значения none свойства display, установка которого скрывает элемент и удаляет его из потока страницы, значение hidden свойства visibility оставляет пустое пространство в том месте, где был бы элемент. cursor позволяет изменять вид указателя мыши, когда он передвигается над определенным элементом. Значения: auto, default, crosshair, pointer, move,eresize, ne-resize, nw-resize, n-resize, se-resize, sw-resize, s-resize, wresize, text, wait, help, progress.
Наследование. Разбивка на страницы Наследование элементами свойств контейнеров Наследование — это механизм, с помощью которого свойства, относящиеся к какомулибо элементу страницы, распространяются и на вложенные в него элементы. Например, поскольку элемент р (абзац) всегда находится внутри элемента body (тело документа), то атрибуты, применяемые к body, наследуются и р. Например, задав CSSсвойство colorэлементу body, вы тем самым установите цвет для всего текста документа (на каком бы уровне вложенности текст ни находился - в абзаце, списке или заголовке). Таким образом, механизм наследования экономит время: без него дизайнеру пришлось бы заботиться отдельно о секциях, абзацах, выделениях и т.п. С другой стороны, естественно, что большинство CSS-свойств вообще не наследуется, например border - иначе бы рамка, заданная, например, для body, появилась бы и во всех списках (в каждом пункте и подпункте), абзацах и других блоках. Как правило,
свойства, которые затрагивают размещение элементов на странице (отступы, поля, рамки элементов), не наследуются. Обычно наследуются следующие основные свойства: color, font, letter-spacing, line-height, list-style, text-align, text-decoration, text-indent, texttransform, visibility, word-spacing. Но и здесь возможны исключения: задание свойств color и font-size для body не повлияет на цвет гиперссылок, а размеры заголовков, хотя и изменятся, но останутся больше размера обычного текста - это вытекает из здравого смысла. body { color: red; font-size: 20px; border: 5px double blue; padding: 5px; } ...
Заголовок 1 уровня
Текст в абзаце. В данном примере элементу body назначены следующие стилевые свойства: цвет текста, размер шрифта, рамка и поле. Как видите, вложенные элементы наследуют эти свойства выборочно. Гиперссылка.
Листинг 4.7. Наследование стилей (html, txt)
Рис. 4.6. Наследование стилей Упражнение. Какие свойства элемента и какими элементами унаследованы в данном примере от свойств body?
page-break-before и page-break-after управляют разрывом страниц. Если применить одно из этих свойств со значением always к какому-либо элементу страницы, то при печати документа будет произведен переход на новую страницу соответственно до или после этого элемента. Существует и ряд других свойств, относящихся к печатному носителю, но они пока не получили единой поддержки во всех браузерах. <style media="print" type="text/css"> .breaking { page-break-after: always; } <style media="screen" type="text/css"> p { border: 2px solid gray; padding: 3px; } ...
В данном примере документ содержит два элемента style - один для представления на экране, а другой - для печати. Экранный стиль назначает всем абзацам рамки и поля, а печатный - ничего.
Данному абзацу назначено стилевое свойство page-break-after: always, в результате чего при печати следующий абзац будет выведен на новой странице.
То, как будет выглядеть напечатанная страница, всегда можно увидеть, воспользовавшись командой меню Файл - Предварительный просмотр.
Листинг 4.8. Свойства, относящиеся к представлению документа на печатном носителе (html, txt)
Рис. 4.8. Предварительный просмотр Упражнение. Попробуйте применить свойство page-break-before. результат в окне предварительного просмотра.
Проверьте
Вопросы 1. Перечислите единицы измерения, применяемые в CSS. Какие из них используются наиболее часто? 2. Какими способами можно задать цвет в CSS? 3. Какие способы применяются для задания размера шрифта? 4. Какие параметры шрифта можно указать при помощи CSS-свойства font? 5. Перечислите основные свойства CSS, относящиеся к тексту. 6. Какие свойства рамок регулируются правилами CSS? 7. Чем отличаются отступы от полей? Какие свойства CSS задают то и другое? 8. Как задать положение и размеры элемента (при абсолютном позиционировании)? 9. Что такое наследование стилей? 10. Какие свойства вызывают разрывы страниц при печати?
"В научном сообществе, в котором зарождалась Всемирная Паутина, людей больше интересовало содержимое документов, нежели их оформление. Как только Интернет открылся для широкой публики, ограничения языка HTML стали источником постоянных разочарований и подтолкнули авторов всячески обходить стилевые ограничения HTML. Все это делалось из лучших побуждений – улучшить восприятие веб-страниц – однако используемые приемы имели далеко не лучшие побочные эффекты. В некоторых случаях и для некоторых задач приемы срабатывали, но не для всех и не всегда. Вот некоторые из применявшихся подходов: • • • • •
Использование собственных расширений HTML Преобразование текста в изображения Использование изображений для заполнения пустого пространства (вместо пробелов) Использование таблиц для верстки страниц Создание программ вместо использования HTML
Подобные методы существенно увеличивали сложность веб-страниц, ограничивали гибкость разработки, страдали проблемами совместимости и создавали почти непреодолимые трудности для людей с ограниченными возможностями." Так характеризуют Рекомендации Веб Консорциума положение дел в веб-дизайне до изобретения Каскадных Таблиц Стилей (Cascading Style Sheet, CSS) (см.http://www.w3.org/TR/html4/present/styles.html. Таблицы стилей решают эти проблемы, вытесняя собой ограниченный набор презентационных механизмов HTML. Они с легкостью регулируют межстрочные интервалы и отступы, цвет текста и фона, шрифты и стили, равно как и множество прочих деталей оформления.
Стандарт HTML 4.01 поддерживает следующие возможности CSS: •
Гибкое размещение стилевой информации Вынос таблицы стилей в отдельные файлы облегчает их повторное использование. Иногда полезно поместить стилевую информацию в самом документе, либо сгруппировав ее в начале документа, либо добавив атрибут стиля к тому или иному элементу. Можно также поместить стилевую информацию в заголовок http и применять ее ко всему сайту.
•
Независимость от конкретного языка таблицы стилей Спецификация языка HTML 4.01 не привязана к какому-либо конкретному языку описания стилей и позволяет использовать целый ряд языков, например некоторый простой язык для большинства случаев и намного более сложный для немногих пользователей со специальными потребностями (глухих, слабовидящих и т.д.)
•
Каскадность Язык CSS позволяет объединять стилевую информацию из нескольких источников. Это могут быть, например, корпоративный набор стилей, стили для группы документов и таблица стилей единичного документа. Раздельное хранение стилевой информации облегчает ее повторное использование и снижает нагрузку на сеть за счет эффективного кэширования. Каскадность определяет упорядоченную последовательность таблиц стилей, при которой правила из более поздних таблиц имеют приоритет перед более ранними. Не все языки таблиц стилей поддерживают каскадность.
•
Зависимость от устройства или носителя информации Язык HTML не накладывает ограничений на устройство, посредством которого будет открыт документ. Таким образом, конечный пользователь может просматривать страницу как на экране компьютера, работающего под управлением Windows, Linux, Macintosh OS или какой-либо другой операционной системы, так и с помощью телевизионной приставки, специального телефонного аппарата, голосового браузера или монитора Брайля (для слабовидящих). Напротив, таблицы стилей привязаны к определенному устройству или группе устройств. Таблица стилей для просмотра на экране может подойти и для печати, но вряд ли полезна для голосового воспроизведения. Стандарт HTML 4.01 позволяют задать категорию устройств, для которых подходит данная таблица стилей и избежать загрузки ненужных таблиц. Язык таблицы стилей может допускать описание нескольких устройств в пределах одной таблицы.
•
Альтернативные стили Разработчик может давать конечному пользователю несколько вариантов просмотра документа, например представления с различным размером шрифта. Стандарт позволяет задать предпочтительную таблицу стилей и альтернативы, предназначенные для отдельных категорий пользователей или носителей информации. Браузер, такой как Internet Explorer 8, позволяет выбирать или полностью отключать таблицу стилей.
Некоторые разработчики высказывали опасения, что внешние таблицы стилей или пространный набор правил в самом документе снижают скорость отображения страницы. В стандарте учтены эти опасения. Разработчик может включать стилевую информацию в любой HTML-элемент, так что она будет доступна браузеру в момент загрузки. Что касается внешних таблиц стилей, то во многих случаях они улучшают производительность и скорость отображения, когда применяются к целой группе документов, поскольку уже присутствуют в кэше браузера во время загрузки второй и последующих страниц.
Добавление стиля в HTML документ Наиболее простым (с точки зрения начинающего разработчика) является добавление атрибута style к HTML-элементу, например:
Этот абзац будет выведен красным
Этот абзац будет выведен зеленым
Этот подход (inline style) удобен в случаях, когда требуется одноразово изменить отображение элемента, однако представьте, что обширная и, часто, одинаковая стилевая информация будет помещена во множество последовательных элементов. Это, во-первых, утяжеляет документ, во-вторых, затрудняет его редактирование (потребуется заменить стили во всех вхождениях), в-третьих, не позволяет применить различные стили для различных носителей информации (экран, принтер и т.д.). Стандарт описывает отделение содержимого (контента) от стилевой информации. Элемент style может быть помещен внутри элемента head HTML-документа. ... <style type="text/css" media="screen"> p { text-align: justify; text-indent: 1cm; } .RedParagraph { color: red; }
Текст обычного абзаца
Этот абзац наследует форматирование обычного абзаца плюс красный цвет текста
... Элемент style имеет ряд атрибутов, из которых обязательным является лишь атрибут type, описывающий язык таблицы стилей (в примере text/css). Атрибутmedia определяет, для какого носителя предназначена стилевая информация;
возможно как единичное значение, так и разделенный запятыми список, например,media=screen,print. Элемент style может находиться только в элементе head и встречаться там любое число раз. Внутри элемента style помещается стилевая информация, называемая правилами. Правила зависят от языка таблицы стилей. Правила CSS будут обсуждены ниже. Наиболее продвинутым является использование внешних таблиц стилей. Этот подход дает целый ряд преимуществ: • • • • • •
Разработчик или администратор сайта может применять одну таблицу для многих документов Разработчик может менять таблицу стилей, не меняя самого документа Средства просмотра (браузеры) могут загружать таблицы стилей селективно, базируясь на типе носителя. Стандарт HTML позволяет включать в документ любое число внешних таблиц стилей; язык таблиц стилей определяет, как эти таблицы будут взаимодействовать между собой Разработчик может определять взаимоисключающие таблицы стилей (называемые альтернативными), и конечный пользователь может выбирать одну из них. Браузер, такой как Internet Explorer 8, позволяет делать такой выбор. Разработчик может определить одну из альтернативных таблиц стилей как предпочтительную, и браузер будет использовать ее по умолчанию.
Внешние таблицы стилей подключаются к HTML-документу при помощи элементов link, которые располагаются в элементе head. Здесь атрибут href задает относительный или абсолютный путь к таблице стилей, type описывает тип содержимого (в данном случае язык таблицы стилей), атрибут rel показывает отношение (relationship) текущего документа к ссылке, определенной в href. Отметим, что rel="stylesheet" без атрибута titleпоказывает, что указанная таблица стилей должна использоваться во всех случаях. описывает предпочтительную таблицу стилей (заданы rel и title) и альтернативную таблицу стилей.
stylesheet
title="Medium"
Разработчик может указать предпочтительную таблицу стилей также при помощи элемента meta (расположенного в элементе head): <meta http-equiv="Default-Style" content="compact"> или в http-заголовке (передаваемом до начала загрузки документа): Default-Style: compact Если предпочтительная таблица стилей указана несколько раз (в элементах meta и/или HTTP заголовке), предпочтение отдается последней в списке. Из двух или более элементов link или style, задающих предпочтительную таблицу стилей, выигрывает первая запись. Элементы meta и HTTP-заголовок имеют преимущество перед элементами link.
Еще одной возможностью подключения внешней таблицы стилей является использование HTTP заголовков. Например: Link: ; rel=stylesheet Эквивалентно При этом следует иметь в виду, что не все браузеры, в том числе Internet Explorer 8, понимают этот метод.
Каскадные таблицы стилей Языки каскадных таблиц стилей, такие как CSS, позволяют объединять стилевую информацию из различных источников. Каскад задается последовательностью элементов link и/или style в элементе head HTML-документа. <style type="text/css"> p.special { color: rgb(230, 100, 180); } В приведенном примере присутствуют две альтернативные таблицы стилей с именем compact. Если пользователь выбирает стиль "compact", браузер должен использовать обе эти таблицы плюс таблицу common.css, присутствующую постоянно, и информацию из элемента style. Если пользователь выбирает стиль "big print", используются таблицы bigprint.css,common.css и элемент style. Каскад может состоять из таблиц, применяемых к различным носителям информации: <style media="screen, print" type="text/css"> p.special { color: rgb(230, 100, 180); } Здесь атрибут media элементов link и style задает тип носителя информации. Голосовой браузер будет использовать только таблицу corporate-aural.css (media="aural"), экран и принтер - corporate-screen.css и corporate-print.css, соответственно, плюс стили из элемента style.
Наследование стилей При отображении страницы браузеру необходимо знать стилевые особенности, например, размер шрифта, цвет, межстрочный интервал и т.д., каждого элемента.
Конкретный механизм процедуры зависит от языка таблицы стилей, но в целом делается следующее: Когда несколько (возможно, противоречащих) правил напрямую применяются к некоторому элементу, используется каскадный механизм. Этот механизм определяет, какие именно правила следует применять. Если правило не найдено, проверяется, может ли оно наследоваться от родительского элемента (наследуются не все атрибуты стиля). Если атрибут не наследуется, используется значение по умолчанию для данного элемента. Если атрибут наследуется, браузер проверяет родительский элемент. Процесс продолжается, пока не найдено подходящее правило. Этот механизм позволяет уменьшить размеры таблицы стилей. Например, разработчик может задать гарнитуру (font-family) элемента body, и она будет применена ко всем отображаемым на страницы элементам.
Правила CSS Стилевая информация каскадной таблицы стилей состоит из отдельных строительных блоков, называемых правилами. Каждое правило, в свою очередь, состоит из двух частей, селектора и объявления стиля, заключенного в фигурные скобки ({}). Селекторы используются для отбора ("селекции") элементов HTML-страницы, к которым будет применено правило. Объявление состоит из пар имя свойства – значение, разделенных двоеточием (:). Пары между собой разделяются точкой с запятой (;). h1 { color: red; font-size: large; } Точка с запятой после последней пары необязательна, однако ее наличие считается хорошей практикой.
Селекторы Простой селектор – это селектор типа либо универсальный селектор (*), за которым сразу (без пробелов) могут следовать селектор ID, селекторы класса и/или псевдокласса. Простые селекторы могут соединяться в цепочку посредством комбинаторов. Комбинаторы указывают контекстные взаимоотношения между селекторами, такие какпотомок, прямой потомок или сосед-родственник. С целью уменьшения размеров таблицы стилей селекторы могут быть сгруппированы в разделенный запятыми (,) список.
Селектор типа Этот селектор указывает тип элемента. h1 {color: red;} Селектор типа соответствует каждому элементу данного типа в документе. В приведенном примере каждый заголовок первого (верхнего) уровня должен отображаться красным цветом.
Универсальный селектор (*) соответствует любому элементу в документе.* (border: solid 1px blue;} В этом примере правило определяет тонкую синюю рамку вокруг каждого элемента. Если универсальный селектор не является единственным компонентом простого селектора, он может быть опущен, например: • •
Селекторы атрибутов Спецификация CSS 2.1 позволяет связывать стилевую информацию с атрибутами HTMLэлементов. Селектор наличия атрибута идентифицирует атрибут (независимо от его значения). [title] {color: атрибут title.
blue;} помечает
синим
элементы,
цветом
имеющие
все
определенный
элементы,
имеющие
a[name]:before {content: "\2660";} помещает символ пиковой масти перед каждой закладкой в документе. Селектор равенства атрибута выбирает элементы, имя и значение атрибута которых в точности совпадает с селектором. a[rel="Copyright"] {color: red;} помечает красным все гиперссылки на страницы с авторскими правами. Селектор частичного совпадения дает соответствие в случае совпадения с одним из значений в разделенном пробелами списке. a[title~="map"] {color: green;} помечает зеленым атрибут title которых содержит слово "map", например, "Site map".
гиперссылки,
Селектор дефиса выбирает элементы, значение атрибута которых либо точно соответствует заданному, либо начинается с заданного с последующим дефисом. [lang|="ru"] {color: red;} [lang|="en"] {color: blue;} Помечает элементы, имеющие атрибут lang (естественный язык) со значением "ru" или "ru-ru", красным, а английский текст (lang="en-us" или lang="en-uk") синим. Как правило, этот селектор применяется для различения естественных языков.
Селектор класса Селектор класса соответствует атрибуту class элемента. p.Bordered {border: solid 1px black;} соответствует абзацам, имеющим атрибут class со значением Bordered. Чтобы применить этот стиль, необходимо (и достаточно) добавить к элементу p атрибут class со значением Bordered,
Имя класса должно следовать сразу после точки (.) без пробела. В простом селекторе может быть задан более чем один класс; точка требуется перед каждым именем. Строчные и заглавные буквы в именах классов различаются. .Bordered.dotted {border-style: dotted;} Соответствует атрибут class со значением Bordered dashed.
элементам,
имеющим
Селектор класса является подмножеством селекторов атрибутов. Правила .myClass {color: red;} и [class="myClass"] {color: red;} эквивалентны. Как отмечает спецификация, "CSS дает настолько большую власть атрибуту class, что разработчики могут создавать собственный "язык документа", основываясь на элементах, практически не имеющих собственного форматирования (таких как div и span), и определяя стилевую информацию через атрибут class . Разработчикам следует избегать этой практики, так как структурные элементы языка документа часто имеют общепринятое значение, тогда как созданные разработчиком классы – нет". Все же следует признать, что концепция классов появилась в CSS существенно раньше введения селекторов атрибутов.
Селектор ID Селектор id позволяет связать правило CSS с уникальным (в пределах страницы) идентификатором элемента, заданного атрибутом id. #miId {text-align: center} Многие браузеры, в том числе Internet Explorer допускают несколько элементов с одинаковым id; в этом случае правило применяется ко всем таким элементам. Пример: <style type="text/css"> p.Bordered { border: solid 1px black; } .Bordered.dashed { border-style: dashed; } #grayBorder { border-color: gray; }
Это абзац классов Bordered и dashed, имеющий также id
Листинг 5.1. Использование селекторов (html, txt)
Рис. 5.1. Использование селекторов
Псевдо-классы Стилевая информация обычно подключается к элементам на основе их положения в дереве документа. Этой модели достаточно в большинстве случаев, однако имеются и распространенные исключения, например, нельзя найти в дереве документа информацию о первой строке абзаца. Спецификация CSS вводит понятия псевдоклассов и псевдо-элементов для применения стилевой информации за пределами дерева документа. Псевдо-классы :link, :visited, :hover и :active применяются к гиперссылке (a) и позволяют менять оформление этого элемента в зависимости от его состояния. a:link { color: Blue; } a:visited { color: yellow;
a:link – обычный вид гиперссылки, которая не относится к "недавно посещавшимся" a:visited – "недавно посещавшаяся" ссылка. Период времени для определения "недавности" различается от браузера к браузеру. a:hover – пользователь навел указатель мыши на ссылку, но не активировал ее a:active – пользователь активирует ссылку (нажимает кнопку мыши на ссылке)
Для того, чтобы псевдо-классы работали, как описано, они должны быть определены именно в этом порядке. В соответствии со Стандартом псевдо-класс :hover может применяться к любому HTMLэлементу, не только к гиперссылке. Это существенно облегчает разработку многих динамических эффектов на странице и позволяет избежать использования программных средств для этой цели. Для использования :hover с элементами, отличными от гиперссылки, HTML-документ должен содержать !DOCTYPE элемент со ссылкой на strict.dtd. Псевдо-класс :first-child позволяет идентифицировать элементы, являющиеся первыми дочерними элементами каких-либо других элементов. Текст не является частью дерева документа и не считается при расчете первого дочернего элемента.
Это <span>первый второй
дочерний
Псевдо-класс :focus применяется как input, select и textarea.
Этот элемент выделяется жёлтым цветом, когда получает фокус ввода:
Пример 5.2. Использование псевдоклассов (html, txt)
Псевдо-элементы Псевдо-элементы :first-letter и :first-line позволяют применить специальное оформление к первому символу и первой строке объекта, соответственно, как это нередко делается в типографских текстах. Объект должен быть блочным элементом, таким как div, p, li. В случае строчных (inline) элементов им требуется задать свойство display: block (т.е. сделать их блочными). p.FirstParagraph:first-letter { font-size: 200%; }
Псевдо-элементы :before и :after позволяют добавлять сгенерированное содержимое перед и после содержимого элемента. p.Note:before { content: "Примечание: "; } добавляет слово "Примечание:" перед абзацем класса Note.
Комбинаторы Нередко разработчику требуется изменить оформление элемента в зависимости от контекста, в котором он находится, например, рядом с какими или внутри каких элементов он расположен. Спецификация CSS позволяет отбирать элементы по этим признакам.
Потомки Соединение двух (или более) простых селекторов пробелом (S1 S2) отбирает элементы S2, находящиеся внутри элементов S1. div.note p {font-size: small;} соответствует любому элементу p (абзацу), являющемуся прямым или более поздним потомком элемента div класса note.
Этот абзац соответствует правилу div.note p
Этот абзац также соответствует правилу div.note p
Чтобы исключить прямых потомков, можно использовать универсальный селектор (*). div.list * p {...} соответствует "внукам" и более отдаленным потомкам. Обратите также внимание, что два следующих селектора различаются p.note {...} p .note {...} Первый соответствует абзацу класса note, второй – любому элементу класса note, являющемуся потомком элемента p (абзаца).
Прямые потомки Комбинация S1>S2 (или S1 > S2) отбирает элементы S2, являющиеся прямыми потомками элементов S1.
body > p {font-size: large;} соответствует абзацам, находящимся непосредственно в элементе body.
Соответствует правилу body > p
Не соответствует правилу body > p
Близкие соседи Комбинация S1+S2 (или S1 + S2) соответствует элементу S2, который следует непосредственно за элементом S1. S1 и S2 должны иметь общий родительский элемент.
Рис. 5.2. Использование комбинаторов Упражнения. Пользуясь комбинаторами, назначьте следующие стилевые свойства: • • • • •
непрямым потомкам секции со сплошной рамкой - зелёный цвет; прямым потомкам секции со сплошной рамкой - красный цвет; заголовку 2-го уровня, идущему сразу за заголовком 1-го уровня - меньший отступ; заголовку в секции с точечной рамкой - размер шрифта 24 пикс; элементам вложенного списка - курсивное начертание.
Специальные правила (at-rules) Специальные правила дополнительно расширяют возможности CSS. Каждое правило начинается с символа "at" (@) и идентификатора и заканчивается, включительно, точкой с запятой (;) или блоком деклараций ({…}), что раньше.
Импорт (@import) Правило позволяет импортировать (подключить) таблицу стилей из внешнего файла. <style type="text/css">
@import "basestyle.css"; p { font-family: Verdana; } эквивалентно <style type="text/css"> p { font-family: Verdana; } Браузер игнорирует @import, если это правило находится внутри блока ({…}) или следует после любого другого правила кроме @import и @charset. Таким образом, следующие записи ошибочны: <style type="text/css"> h1 { color: red; } @import "mystyle.css"; <style type="text/css"> @import "mystyle.css"; @media print { @import "print-style.css"; Body { background: white; } Правильными конструкциями будут: <style type="text/css"> @import "mystyle.css"; h1 { color: red; } <style type="text/css"> @import "mystyle.css"; @import "print-style.css" print; @media print { body { background: white; }
Носитель (@media) Это правило позволяет задавать набор правил для различных типов носителей в пределах одной таблицы стилей. <style type="text/css"> @media screen { body {
background: blue; color: white; } /* body */} /* @media */ @media print { body { background: transparent; color: black; } /* body */} /* @media */ Эквивалентная запись выглядит следующим образом: <style type="text/css" media="screen"> body { background: blue; color: white; } <style type="text/css" media="print"> body { background: transparent; color: black; } Спецификация CSS 2.1 определяет следующие типы носителей: • • • • • • • • • •
screen – цветной экран монитора print – принтер или экран монитора в режиме предварительного просмотра печати speech (в спецификации CSS 2 aural) – голосовой синтезатор projection – проектор. В отличие от монитора, предполагает постраничное представление handheld – небольшие устройства с низким разрешением экрана и ограниченной шириной полосы пропускания, например, сотовые телефоны tv – телевизор (низкое разрешение, цвет, ограниченная прокрутка, звук) brail – экран для людей с пониженным зрением, работающий по системе Брайля embossed – принтер Брайля tty – телетайп или устройство с ограниченными возможностями экрана all – любое устройство
Типы носителей взаимоисключающи, однако одно и то же устройство может работать в нескольких режимах, например экран монитора в обычном режиме и режиме просмотра печати.
Печатная страница (@page) Это правило определяет размеры, ориентацию и поля печатной страницы. @page {margin: 3cm;}задает поля шириной 3 см. Псевдо-классы :left, :right и :first позволяют задать специальные правила для левой, правой (при двухсторонней печати) и первой страницы.
@page :left { margin-left: 4cm; margin-right: 3cm; } @page :right { margin-left: 3cm; margin-right: 4cm; } @page :first { margin-top: 10cm /* Верхнее поле для первой страницы 10 см */; }
Кодировка (@charset) Это правило задает кодировку внешней таблицы стилей, должно присутствовать не более одного раза и располагаться в самом начале файла. @charset "Windows-1251"; /* Кириллица Windows */
Внедренный шрифт (@font-face) Это правило позволяет разработчику загрузить специфический шрифт, отсутствующий на клиентской машине. @font-face { font-family: "MyFont"; src: url(FontSourceFile.eot); } h1 { font-family: "Verdana" , "MyFont"; }
Специфичность и порядок применения правил Конфликт правил неотделим от каскадных таблиц стилей. Когда два или более объявления подходят к одному элементу, браузер должен решить, какое именно применить. Internet Explorer применяет следующий алгоритм: • •
•
Отбираются все подходящие объявления, включая наследованные, которые подходят к данному типу носителя (@media) Объявления отсортировываются по весу и происхождению. Стили разработчика перевешивают стили пользователя (которые перевешивают встроенные стили браузера), если только пользовательское объявление не содержит пометки !important (важно), которая увеличивает вес объявления. Селекторы правил отсортировываются по специфичности, рассчитываемой как число, полученное строковым слиянием (a) наличия атрибута style у элемента, (b) числа атрибутов id, (c) числа атрибутов class и псевдо-классов и (d) числа типов элементов и псевдо-элементов в селекторе. Если элемент содержит атрибуты, влияющие на представление (например, атрибут width элемента table) то эти атрибуты преобразуются в соответствующие CSS атрибуты с нулевойспецифичностью. Например, любой из перечисленных селекторов может применяться к элементу li, но лишь правило с наибольшей специфичностью будет применено.
Селектор
Атрибут style (a)
Число Число Число классов типов Специфичность атрибутов id (b) (c) (d)
Если два правила имеют равный вес и специфичность, применяется прочитанное последним. (Импортированные при помощи @import таблицы стилей всегда проигрывают записанным позже.)
Вопросы • • • • • • • • • •
Какими способами можно связать HTML-документ с таблицей стилей? Из чего состоит правило CSS? Что такое простой селектор? Что выбирает селектор типа? Что выбирает селектор класса? Что выбирает селектор ID? Какой смысл придают правилу CSS комбинаторы потомков и соседей? Перечислите и охарактеризуйте определяемые CSS псевдоклассы и псевдоэлементы. Какие типы носителей определяет спецификация CSS? Как связать таблицу стилей с носителем? Как разрешаются конфликты определения стилей?
6. Лекция: Позиционирование средствами CSS Типы позиционирования элементов в CSS и их особенности. Позиционирование на основе плавающих элементов. Приёмы центрирования и наложения элементов. Содержание •
Статическое и абсолютное позиционирование
o o •
Позиционирование на основе плавающих элементов. Центрирование элементов на странице
Относительное и фиксированное позиционирование. Наложение элементов
o o o •
Абсолютное позиционирование.
Позиционирование на основе плавающих элементов. Центрирование
o o •
Основной механизм позиционирования. Нормальный поток.
Относительное позиционирование Фиксированное позиционирование Наложение элементов
Вопросы
CSS предлагает четыре типа позиционирования. •
•
•
•
Абсолютное (position:absolute;). Такое позиционирование позволяет определять расположение элемента, задавая позиции left, right, top или bottomв любых единицах измерения CSS. Кроме того, абсолютно размещенные элементы полностью изъяты из потока страницы, определенного HTML-кодом: остальные элементы на странице размещаются без учёта абсолютно позиционированных элементов. Относительное (position:relative;). Элемент с таким позиционированием размещается относительно его текущего положения в потоке HTML. Так, например, устанавливая значение top равным 20 пикселов и значение left равным 200 пикселов для относительно размещенного заголовка, вы переместите его на 20 пикселов вниз и 200 пикселов влево от того места, где он появился бы на странице. В отличие от абсолютного позиционирования, здесь остальные элементы страницы регулируют старое HTML-размещение относительно позиционированного объекта. Соответственно, перемещение объекта с относительным позиционированием оставляет "дыру", на месте которой он должен был находиться. Основная польза относительного позиционирования не в том, чтобы переместить элемент, а в установке новой точки привязки для абсолютно позиционированных элементов, которые вложены в него. Фиксированное (position:fixed;). Фиксированный элемент закрепляется в определенном месте на экране. Определение такого позиционирования играет ту же роль, что и установка значения fixed для свойства backgroundattachment при позиционировании фоновых изображений. Когда посетитель прокручивает страницу, фиксированные элементы остаются на экране как абзацы и заголовки, в то время как фотографии прокручиваются вместе со страницей. Использование фиксированных элементов — отличный способ создать неподвижное боковое меню или воспроизвести эффект HTML-фреймов, где только определенная часть страницы прокручивается. Статическое позиционирование соответствует нормальному потоку HTML.
Статическое и абсолютное позиционирование Основной механизм позиционирования. Нормальный поток. В отсутствие каких-либо дополнительных указаний (в виде правил CSS или атрибутов HTML) браузер размещает содержимое на странице по следующим правилам:
Ширина блочного элемента равна ширине его контейнера; ширина строчного элемента такова, как требует его содержимое. Высота и для блочных, и для строчных элементов равна высоте их содержимого. Браузер размещает элементы в их контейнерах слева направо, затем сверху вниз, начиная с контейнера body.
body { background-image: url(Pos_divs_body.png); } div { color: Blue; border: solid 1px blue; margin: 2px; padding: 4px; font-size: large; } div div { color: Red; border: solid 1px red; } ...
Это текст в контейнере div - Lorem ipsum...
Это текст в контейнере div - Lorem ipsum...
Это текст в контейнере div - Lorem ipsum...
Листинг 6.1. Нормальный поток (html, txt)
Рис. 6.1. Нормальный поток Упражнение. Откройте пример в отдельном окне и убедитесь, что все div-контейнеры всегда занимают всю ширину окна, независимо от её величины. Уменьшите ширину
контейнеров div (например, width:40%;) и убедитесь, что появившееся пространство остаётся незаполненным. Очевидно, что, если документ состоит из набора контейнеров, то в рамках нормального потока можно как угодно управлять их взаимным положением по вертикали и смещением по горизонтали относительно границ окна пользуясь свойствами margin и width. Однако в нормальном потоке невозможно разместить два (и более) смежных по горизонтали блока: любой блочный элемент всегда занимает всю ширину своего контейнера. Невозможно дать браузеру команду: "Элемент X следует разместить справа (слева) от элемента Y", не прибегая к использованию других механизмов.
Абсолютное позиционирование. Принципиально другой механизм заключается в полном извлечении (выбрасывании) элемента из потока и размещении его в указанной позиции - относительно контейнера. <style type="text/css"> body { padding: 0; margin: 0; } div { border: solid 1px blue; padding: 4px; } .static { color: Blue; padding: 2em; } .abs { position: absolute; top: 0px; right: 0px; color: Red; border: solid 1px red; } ...
Это текст в обычном (статически позиционированном) контейнере div Lorem ipsum...
Этот контейнер div позиционирован абсолютно вправо (top: 0px; right: 0px;) - Lorem ipsum dolor sit amet
Листинг 6.2. Абсолютно позиционированный блок в правом верхнем углу (html, txt)
Рис. 6.3. Абсолютно позиционированный блок в абсолютно позиционированном блоке Очевидно, абсолютное позиционирование даёт полную свободу поместить любой элемент в любую точку - достаточно знать её координаты, выраженные в какой-либо из единиц измерения CSS. Однако часто координаты заранее неизвестны (они могут зависеть, например, от высоты текстового блока). В этом случае средства абсолютного позиционирования недостаточно. Нет способа выразить, например, такую команду: "Элемент X следует поместить слева (справа, сверху, снизу) от элемента Y".
Позиционирование на основе плавающих элементов. Центрирование Позиционирование на основе плавающих элементов. Не существует такого вида позиционирования как "плавающий", и "плавающие" элементы должны быть позиционированы статически (что автоматически достигается при отсутствии определения свойства position). Однако свойство floatпозволяет модифицировать нормальный поток ещё одним способом. "Плавающий" (floating) элемент примыкает к левой (float:left) либо правой (float:right) границе своего контейнера, а последующие элементы (как блочные, так и строчные) обтекают его с противоположной стороны. Это нашло чрезвычайно широкое применение в CSSвёрстке (об этом говорится в отдельной лекции). div { width: 40%; float: left; margin: 3px;
Рис. 6.5. Плавающий блочный элемент и обтекающий его слева текст Упражнения. • • • •
Уберите указание ширины контейнеров. Почему пропал эффект плавающей разметки? Добавьте третий контейнер, добейтесь размещения всех контейнеров в один горизонтальный ряд. Что произойдёт, если упаковать все div-контейнеры в ещё один div-контейнер? В примере с обтекающим текстом увеличьте отступ для плавающего контейнера (чтобы обтекающий его текст располагался дальше от рамки). Контейнер в рамке не должен опуститься вниз.
Центрирование элементов на странице Если задать блочному элементу значение auto в свойствах margin-left и marginright, то он центрируется по горизонтали в своём контейнере. При этом у элемента должна быть задана ширина. Для старых браузеров (IE5-) этот приём не срабатывает, и тогда применяются менее изящные способы. Чтобы центрировать строчный элемент (например, img), его обычно помещают в блочный (либо назначают ему свойство display:block, тем самым делая блочным его самого). Для вертикального центрирования применяют другую технологию: позиционируют блочный элемент абсолютно левым верхним углом в центр экрана (top:50%; left:50%;) и затем смещают влево и вверх путём задания отрицательных отступов. div { margin-left: auto; margin-right: auto;
Рис. 6.7. Вертикальное центрирование Упражнение. Разместите в центре страницы изображение с подписью.
Относительное и фиксированное Наложение элементов
позиционирование.
Относительное позиционирование Один из эффективных приёмов позиционирования состоит в том, чтобы размещать маленькие объекты относительно других объектов на странице, например, блок внутри блока. Для этого блок-контейнер позиционируют относительно (при этом он остаётся на месте и не выбивается из нормального потока), а внутренний блок - абсолютно. Точнее, абсолютная позиция отсчитывается от первого блока в ряду контейнеров, который имеет позиционирование absolute, relative или fixed (но неstatic). Если такого контейнера нет, то им считается окно. Пример 6.8 показывает размещение абсолютно позиционированного элемента span в правом нижнем углу его контейнера div. div { width: 70%; border: 4px dotted gray; padding: 4px; padding-bottom: 30px; position: relative; margin: 10px auto; } div span { position: absolute; bottom: 0; right: 0; background: #ddd;
<span>Внутренний блок 1 Один из эффективных приёмов позиционирования состоит в том, чтобы размещать маленькие объекты относительно других объектов на странице, например, блок внутри блока. Для этого блок-контейнер позиционируют относительно (при этом он остаётся на месте и не выбивается из нормального потока), а внутренний блок - абсолютно.
<span>Внутренний блок 2 Данный пример показывает размещение абсолютно позиционированных элементов span в правых нижних углах их контейнеров. Внутренние блоки позиционированы посредством задания свойств bottom: 0; right: 0;
Листинг 6.8. Применение относительного позиционирования (html, txt)
Рис. 6.8. Применение относительного позиционирования Упражнение. Позиционируйте элемент span в правый верхний угол секции. Подберите для секции подходящее значение отступа. Таким образом, все основные задачи позиционирования можно решить, только пользуясь всеми тремя описанными подходами:
для стыковки блоков по горизонтали применяется позиционирование на основе плавающих элементов; для стыковки блоков по вертикали применяется позиционирование на основе нормального потока; для размещения блока в специфической позиции относительно контейнера применяется абсолютное позиционирование блока в сочетании с относительным позиционированием контейнера.
Упражнения. Придумайте разметку для такой структуры блоков: один сверху на всю ширину окна; ещё три - под ним, в один горизонтальный ряд, одинаковой ширины (с небольшими полями между блоками).
Фиксированное позиционирование Часто бывает нужно, чтобы некоторые элементы страницы были постоянно видимыми, например, навигационная панель, поле для поиска или логотип сайта, а, как известно, большинство веб-страниц длиннее высоты экрана. Используя значение fixed свойства position, вы можете зафиксировать некоторые элементы в определенных местах, разрешая при этом пользователям прокручивать содержимое очень длинной веб-страницы. Фиксированное позиционирование работает во многом подобно абсолютному — вы точно так же можете использовать свойства top, bottom, left или right для размещения элемента. Как и абсолютное, фиксированное позиционирование удаляет элемент из потока HTML. Он "плавает" над другими частями страницы, которые просто игнорируют его. Фиксированное позиционирование не работает в Internet Explorer версий 6 и ниже. div { margin-left: 210px; } .fixed { position: fixed; left: 10px; top: 100px; list-style-position: inside; margin: 10px; border: 1px solid black; background: #ccc; padding: 3px; width: 170px; } ...
Это список,
позиционированный фиксированно
в точке (10px; 100px)
Это длинный блок текста, и для его полного просмотра нужно прокручивать страницу вниз. Фиксированно позиционированный список при этом остаётся на месте.
...
Листинг 6.9. Применение фиксированного позиционирования (html, txt)
Рис. 6.9. Применение фиксированного позиционирования Упражнение. Переместите фиксированный блок в правую часть страницы. Подберите отступ для основного содержимого.
Наложение элементов В нормальном потоке элементы не накладываются друг на друга, а при остальных способах позиционирования это очень легко может произойти. Какой же всё-таки элемент должен оказаться сверху - можно указать при помощи общего свойства zindex, принимающего произвольное целое неотрицательное значение. img { position: absolute; width: 50%; } img:hover { z-index: 1000; } ... Листинг 6.10. Наложение элементов. Применение свойства z-index (html, txt)
Рис. 6.10. Наложение элементов Упражнение. Измените порядок наложения изображений на противоположный, задав каждому из них атрибут z-index. Упражнения. • •
Поместите всплывающую подсказку а) в левый верхний угол изображения; б) ниже левого нижнего угла. Уберите встроенные стили у всех секций и установите свойство position в relative.
Вопросы 1. 2. 3. 4. 5. 6.
Перечислите типы позиционирования CSS. Каковы правила размещения элементов в нормальном потоке? Охарактеризуйте абсолютное позиционирования и область его применения. Как задаётся позиционирование на основе плавающих элементов? Для чего обычно применяется относительное позиционирование? Как достичь центрирования элемента на странице по горизонтали и по вертикали? 7. Как работает фиксированное позиционирование? 8. Как можно регулировать порядок наложения элементов?
7. Лабораторная работа: Создание динамического меню навигации при помощи списков и правил CSS Цель. Научиться применять элементы HTML (списки и гиперссылки), а также свойства CSS (модель отображения, псевдоклассы гиперссылок) для формирования системы навигации на веб-странице.
Разместить на странице меню с набором гиперссылок - одна из важных задач в практике веб-дизайнера. Чтобы не утомлять внимание пользователя просмотром всего набора, ссылки обычно группируют по категориям, и в основное меню включают только категории. Только при выборе категории должны отобразиться соответствующие ссылки (или подкатегории). Как правило, такие динамические меню принято создавать средствами языка Javascript, позволяющего совершать любой сложности манипуляции с элементами веб-страницы. Однако, существует и решение на CSS - довольно простое и красивое, хотя и не любую фантазию дизайнера выполняющее. Рассмотрим его пошагово. В этой работе (и нескольких следующих) воспользуемся специализированным редактором, например, Microsoft Visual Web Developer. Мы рекомендуем именно его, поскольку он бесплатен, а, совершенствуясь профессионально, вы можете перейти на Microsoft Visual Studio - одно из лучших средств разработчика самого широкого круга приложений. Для студентов Visual Studio в настоящее время также предоставляется бесплатно (см. http://dreamspark.ru ). 1. Запустите Visual Web Developer (или Visual Studio) и создайте новый документ HTML. 2. Внутри элемента head введите подходящий заголовок страницы. 3. Введите открывающий тэг <style>. Обратите внимание, что программа даёт подсказки по мере набора текста (эта технология называется Intellisense): введя открывающую угловую скобку, вы видите перечень html-элементов, а введя пробел после имени элемента, вы видите перечень допустимых имён атрибутов данного элемента (в данном случае необходим атрибут type). Поставив знак равенства после имени атрибута, вы можете увидеть список его допустимых значений (в тех случаях, когда такой список существует в принципе). Всякий раз значение можно выбрать из списка щелчком мыши либо, если по мере ввода оно выделилось автоматически, просто нажать Enter или пробел. 4. После ввода закрывающей угловой скобки редактор автоматически добавит закрывающий тэг . 5. Создайте в теле документа набор категорий в виде неупорядоченного списка (ul), каждый элемент которого содержит список ссылок (см. пример). 6.
Листинг 7.1. Разметка списка категорий и ссылок (html, txt)
Названия ссылок и категорий придумайте самостоятельно. Важно, чтобы атрибут id внешнего списка имел значение MainMenu - далее ему будет назначен особый стиль по этому идентификатору). 52. В таблице стилей добавьте следующее правило: 53. #MainMenu > li { 54. float: left; 55. list-style-type: none; 56. } Отслеживайте изменения, происходящие с отображением документа, разделив окно редактора на представление исходного кода и конструктора. После применения указанного стилевого правила пункты внешнего списка (li) расположились горизонтально (за счёт обтекания):
Рис. 7.1. Работа с HTML-документом в Visual Web Developer 57. Пусть вложенные списки ссылок будут невидимыми (добавьте им свойство display:none;) и появляются только при наведении курсора на название соответствующей категории. Следующее правило с селектором псевдокласса hover имеет такой смысл: у списка (ul), вложенного в пункт списка (li), на который наведён указатель (:hover) и который вложен в элемент с id=#MainMenu, способ отображения следует сделать блочным (а не невидимым): 58. #MainMenu li:hover ul { 59. display:block; 60. } Сохраните разрабатываемый документ, откройте его в браузере и убедитесь, что меню работает правильно. 61. Принципиально механизм работает - осталась эстетическая сторона. o Назначьте якорям любого уровня вложенности в меню (правило #MainMenu a) желаемый цвет (color), гарнитуру (font), а также уберите подчёркивание (text-decoration). o Назначьте элементам списка категорий (правило #MainMenu > li) фоновый цвет (background), внутренний отступ (padding) и рамку справа (border-right). o Назначьте элементам вложенного списка ссылок (правило #MainMenu li li) такой же фоновый цвет, как и в списке категорий, а также небольшой отступ и рамку снизу. Кроме того, уберите маркировку списка (liststyle-type). o Уберите у списка ссылок (правило #MainMenu li ul) поля и отступы (margin и padding).
Небольшой проблемой является то, что некоторые элементы списка категорий увеличиваются в ширину при наведении на них указателя. Это является следствием того, что ширина элемента списка определяется шириной всего содержимого - включая вложенный список. Однако если выбросить вложенный список из нормального потока и позиционировать его абсолютно, то его ширина более не будет влиять на ширину родительского элемента. Поэтому укажите для списка ссылок абсолютное позиционирование, а для элементов списка категорий - относительное. Проверьте в браузере. Затем уточните положение вложенного списка относительно его контейнера путём задания значения свойств left и top (не опускайте выпадающий список слишком низко, иначе он станет пропадать при попытке выбрать в нём ссылку). Зачем нужно было позиционировать элементы списка категорий относительно? Уберите соответствующее правило, и вам всё станет ясно. 62. Добавьте последний штрих: пусть элементы обоих списков при наведении указателя немного изменяют цвет фона (правило #MainMenu li:hover). Окончательный результат должен быть подобен следующему:
Рис. 7.2. Меню с выпадающими списками ссылок в действии Анализируя полученный результат, можно придти к выводу, что реализация на CSS достаточно лаконична, очевидна и независима от исходной разметки. Сама же разметка имеет ясную логическую структуру - списки ссылок, вложенные в список категорий. Общая структура и основные взаимосвязи элементов в документе показаны на рис. 7.3 (использована нотация UML).
Рис. 7.3. Структура меню и стили, воздействующие на отображение его элементов Смысл диаграммы достаточно очевиден: в элемент HTML ul#MainMenu включается 5 элементов li, к каждому из которых применяется правило CSS #MainMenu > li, определяющее такие свойства как float, background, padding, border и position и т.д. Необходимо, однако, добавить, что, хотя в данном примере это и не играет существенной роли, но стилевые свойства, применяемые к элементам, определяются не только из таблицы стилей. Также источниками стилевых свойств являются встроенные определения стиля и браузерные стили по умолчанию. Что же касается свойств, определённых в таблице стилей, то некоторые из них могут наследоваться элементами HTML от их контейнеров - так, например, цвет и большинство других атрибутов текста, будучи указаны тем или иным образом для элемента body, наследуется и всеми вложенными в него элементами. Задание. Самостоятельно модифицируйте вертикальное меню категорий.
Размещение изображения в документе. Поддерживаемые графические форматы. Указание размера
o • • •
Общие свойства. Обтекание текстом Фоновые изображения Ролловеры. Карты
o o •
Элемент img
Ролловеры Атрибуты ismap и usemap
Вопросы
В первую очередь под изображениями подразумеваются, конечно, фотографии и другая предоставляемая читателю графическая информация. Однако при вёрстке HTMLстраниц изображения часто используются и там, где, с точки зрения здравого смысла, без них можно было бы и обойтись. Для создания красивой градиентной заливки фона приходится пользоваться заранее подготовленными точечными рисунками, поскольку средствами CSS 2 можно создать лишь однотонную (а не градиентную) заливку. Если в HTML-документе должны быть показаны формулы, то их, как правило, подготавливают в специальном редакторе и экспортируют как gif- или png-изображения (хотя существует язык определения формул MathML, основанный на XML, но для него нет единой поддержки всеми браузерами). Чертёж, состоящий из набора линий, простых фигур и текста, тоже придётся вставлять как изображение (хотя существует язык определения векторной графики SVG, но некоторые популярные браузеры не поддерживают его). Красивые рамки с закруглёнными углами, выноски, заголовки нестандартным шрифтом и многое другое - на сегодняшний день не реализуемо единым для всех современных браузеров способом, если не прибегать к изображениям (или специальным трюкам). Рассмотрим, какие средства для работы с изображениями предоставляют языки разметки гипертекста и каскадных стилей.
Размещение изображения Поддерживаемые графические размера
в документе. форматы. Указание
Элемент img Применяется как основной способ вставки изображения в HTML-документ: Элемент img - строчный, и его можно вставлять непосредственно в текст абзаца, пункт списка или ячейку таблицы - при этом не происходит начала новой строки. К необходимым атрибутам относятся src (источник) - путь к изображению, который может быть указан относительно текущего HTML-документа (flower1.jpg ; images/flower1.jpg и т.п.), относительно от корневого каталога сайта (/images/flower1.jpg) либо абсолютно (http://site.com/images/lower1.jpg), а также alt альтернативный текст, отображаемый в том случае, когда изображение не показывается (например, если показ изображений отключен в настройках браузера) и произносимый синтезатором речи.
Допустимые форматы изображений стандартом не определены, и браузеры могут вести себя по-разному, однако фактически стандартами стали форматы GIF, JPEG и PNG: • • •
Формат GIF (Graphics Interchange Format) - сжатие изображения без потерь, с поддержкой прозрачности и анимации, 8-битный цвет (256 вариантов); Формат JPEG (Joint Photographic Experts Group) - сжатие регулируемой глубины с потерями, 16-битный цвет; Формат PNG (Portable Network Graphics) сжатие регулируемой глубины, широкий выбор цветовых форматов (24-битный цвет, оттенки серого, 8-битовая цветовая палитра), поддержка многослойной прозрачности.
Как правило, JPEG хорош для фотографий, позволяя достичь наилучшего сжатия с минимальными потерями, а GIF и PNG - для схем и пиктограмм. Также часто для элемента img указывают ширину и высоту посредством задания значения атрибутов width и height. Браузер не может верно скомпоновать макет страницы, не зная размеров входящих в неё изображений, поэтому в том случае, если эти атрибуты не указаны, браузер должен будет делать отдельный запрос к вебсерверу (изображения всегда загружаются отдельно от разметки). Возможны ситуации, когда браузеру знать размеры изображения необходимо, но загружать само изображение не нужно, поэтому width и height рекомендуется, как правило, указывать. Очевидно, эти атрибуты позволяют также изменять масштаб и пропорции изображения на веб-странице, однако, следует иметь в виду, что увеличение масштаба для точечных изображений всегда ведёт к существенной потере качества, а уменьшение таким способом, как правило, не вполне оправдано: если изображение должно быть меньше, то почему бы не уменьшить сам файл изображения? Иначе по сети передаётся больший объём, чем необходимо. Возможно указание размеров изображения в процентах от ширины окна браузера (обычно указывают ширину, а высота устанавливается браузером исходя из соблюдения пропорций). В этом случае изображение может быть растянуто слишком сильно - для ограничения ширины следует использовать свойство max-widthсо значением в пикселах. <style type="text/css"> .percent_size { width: 30%; min-width: 200px; } img { margin: auto; } Листинг 8.1. Процентное задание размеров изображений (html, txt)
Рис. 8.1. Процентное задание размеров изображений Упражнение. Откройте пример в новом окне и убедитесь, что изображение изменяет свою ширину пропорционально ширине окна браузера, но не уменьшается после указанного предела (Windows Explorer ведёт себя при уменьшении довольно странно). Добавьте ограничение сверху на ширину изображений, просмотрите страницу в действии.
Общие свойства. Обтекание текстом CSS позволяет использовать для позиционирования и оформления изображений общие свойства, в первую очередь следующие: • • • •
border - для обрамления изображений; padding - для создания пространства между изображением и его рамкой; float - для выравнивания изображения по левому или правому краю контейнера (при этом текст обтекает изображение с другой свободной стороны и под ним); margin - отступ от соседних элементов страницы.
Рассмотрим свойство float (в отличие от остальных общих свойств, оно обычно применяется к изображениям с несколько другой целью по сравнению с другими элементами). Именно для создания такого эффекта как обтекание изображения текстом это свойство главным образом и предназначалось - затем его стали применять для многоколоночной вёрстки. Сам принцип обтекания достаточно очевиден: нужно просто назначить изображению свойство float:left или float:right при помощи стиля. Сложнее разобраться в сопутствующих эффектах. Во-первых, как правило, изображению в этом случае следует назначать отступ с примыкающей к тексту стороны. Во-вторых, обтекание всегда необходимо вовремя останавливать: иначе изображение будет обтекаться не только последующим текстом, но и последующими изображениями. Следует назначать значение clear:both элементам, которые уже не должны обтекать изображения. И, наконец, контейнеры, содержащие плавающие элементы имеют неприятную особенность неправильно определять собственную высоту (не учитывается высота плавающего элемента). Противодействие существует: свойство overflow: hidden, применённое к контейнеру плавающего элемента, труднообъяснимым образом решает эту проблему. .left { float: left; margin-right: 8px; } .right {
float: right; margin-left: 8px; } div { margin: 8px 0; overflow: hidden; } p { margin: 0; } ...
Этот текст обтекает изображение, т.е. занимает свободное пространство сбоку и снизу от него. При помощи CSS данный эффект достигается за счёт применения к обтекаемому объекту свойства float со значением left или right. Обычно при этом указывают ещё и отступ (margin).
Изображения вместе с текстом заключены в данном примере в секции, которым назначен небольшой вертикальный отступ (margin: 8px 0). Свойство clear:both назначать здесь нет необходимости, поскольку секция стремится занять 100% ширины своего контейнера, и не станет обтекать другие элементы (если её ширину специально не ограничить). Контейнеры, содержащие плавающие элементы имеют неприятную особенность неправильно определять собственную высоту (не учитывается высота плавающего элемента). В качестве противодействия элементам div в данном примере назначено стилевое свойство overflow: hidden, которое решает эту проблему.
Рис. 8.2. Обтекание изображений текстом Упражнение. Сделайте, чтобы оба изображения размещались слева. Проверьте, что будет, если: а) убрать свойство clear у div; убрать там же свойствоoverflow; в) убрать сброс отступов у параграфов. Каким образом эти свойства влияют на отображение страницы?
Фоновые изображения Представляют собой мощный механизм внесения разнообразия в визуальное представление страницы. Фоновое изображение (одно в CSS 2, и несколько в CSS 3) можно назначить практически любому блочному элементу - body, div, table, ul и т.д.: background-image: url(файл); Путь к файлу может быть, как обычно, абсолютным, относительным или корневым. По умолчанию изображение повторяется в обоих направлениях, заполняя всю площадь элемента, которому оно назначено. Дополнительные CSS-свойства позволяют управлять размещением изображения.
Свойство background-repeat определяет правило повтора: возможны значения norepeat, repeat-x, repeat-y и repeat, смысл которых очевиден. Свойство background-position определяет начальную позицию изображения. Для этого свойства требуется указать два значения - смещения по X и по Y от левого верхнего угла элемента. Значения могут быть заданы в любых единицах измерения CSS, а также ключевыми словами left, center, right (для указания горизонтальной позиции) и top, center,bottom (для вертикальных). Ещё одно свойство - background-attachment - позволяет закрепить изображение в определённом месте окна браузера, сделав его независимым от прокрутки: background-attachment:fixed; Значение этого свойства по умолчанию - scroll (прокручиваться). И, наконец, сокращённое свойство background позволяет указать сразу перечисленные свойства фоновых изображений (а также background-color): background: [background-color] [background-image] [background-attachment] [background-position]
все
[background-repeat]
Могут быть указаны не все эти свойства, а только те, которые должны отличаться от значений по умолчанию. body { padding-left: 100px; background-image: url(Texture.jpg); background-repeat: repeat-y; } ...
Заголовок 1 уровня
Фоновое изображение (одно в CSS 2, и несколько в CSS 3) можно назначить практически любому блочному элементу - body, div, table, ul и т.д.: background-image: url(файл);
По умолчанию изображение повторяется в обоих направлениях, заполняя всю площадь элемента, которому оно назначено. Дополнительные CSS-свойства позволяют управлять размещением изображения. В данном примере изображение повторяется только по вертикали, поскольку задано свойство backgroundrepeat: repeat-y.
Рис. 8.3. Фоновые изображения Упражнения. Разместите фоновую текстуру горизонтальной полосой а) над текстом; б) под ним. Создайте две горизонтальных полосы текстур - сверху и снизу текста. Для этого поместите в тело документа секцию, с полосой текстуры вверху; внутри этой секции ещё одна секция с полосой текстуры внизу. Весь текст поместите во вложенную секцию. Добейтесь того же эффекта, как и в предыдущем упражнении, заполнив внешнюю секцию текстурой полностью, а для внутренней установив фоновый белый цвет. Примерный вид результата см. на рис. 8.4.
Рис. 8.4. Горизонтальные полосы текстур С фоновыми изображениями связан ряд трюков. Рассмотрим задачу создания специфической рамки (отличной от обычного прямоугольника) вокруг блочного элемента (рис. 8.5). В CSS 3 для этого есть встроенный механизм, а в CSS 2 - нет, поэтому нет альтернативы применению изображения. Чтобы предусмотреть возможные изменения в высоте элемента, вокруг которого создаётся рамка, изображение делится на две части, первая из которых размещается сверху блока, а вторая - снизу, так, что, блок, расширяясь, как бы раздвигает собой рамку. Но в CSS 2 нет и возможности назначить одному блоку два фоновых изображения (а в CSS 3 есть)! Поэтому блока должно быть тоже два, причём один вложен в другой. div { background-image: url(rnd_bot.png); background-position: left bottom; background-repeat: no-repeat; width: 200px; } h3 { background-image: url(rnd_top.png); background-position: left top; background-repeat: no-repeat; margin: 0; padding: 12px; padding-bottom: 5px; }
p { padding: 12px; padding-top: 0; margin: 0; } ...
Заголовок 3 уровня
Изображение разделено на две части, первая из которых назначена в качестве фона заголовку: background-image: url(rnd_top.png). Фон заголовка размещён слева вверху (background-position: left top) и без повтора (backgroundrepeat: no-repeat).
Нижняя часть изображения назначена фоном секции (в которую входят и заголовок, и абзацы). Оно позиционировано слева внизу и также без повтора.
Листинг 8.4. Создание рамки при помощи фоновых изображений (html, txt)
Рис. 8.5. Создание рамки при помощи фоновых изображений Упражнения. Попробуйте увеличивать и уменьшать количество текста в заголовке и в абзаце, чтобы выяснить границы применения рассматриваемого приёма. Создайте новый HTML-документ с несколькими заголовками и абзацами. Нарисуйте от руки в редакторе Paint (или любом другом) волнистую горизонтальную линию небольшой длины. При рисовании постарайтесь, чтобы начальная и конечная точки находились примерно на одном уровне по вертикали, и чтобы кривая в этих точках имела примерно одинаковый наклон. Сохраните рисунок в формате png и при помощи CSS-правила для элемента заголовка поместите его в HTML-документ. Заголовки должны подчёркиваться линиями. Изменение ширины блока очевидно, рассмотренным трюком не предусматривается. Однако, развивая идею, можно увеличить количество задействованных блоков и изображений до четырёх, что решает эту проблему.
Ролловеры. Карты Ролловеры Под термином "ролловер" в веб-дизайне понимают визуальный элемент (например, кнопку), меняющий свой вид таких действиях указателя мыши как наведение и нажатие. Элементы навигации в лабораторной работе 2 можно считать ролловерами, однако часто ролловеры полностью меняют изображение, а не только цвет. Разумеется, этого можно достичь теми же средствами, т.е. определить различные фоновые изображения ролловера в различных состояниях (для гиперссылки, например, таких состояний четыре - link, visited, hover и active). Однако сменное изображение, загружаясь впервые, создаст ощутимую задержку, что нежелательно. Возможность регулировать позицию фонового изображения предоставляет возможность решения этой проблемы: изображения для всех состояний объединяются в одно, и при смене состояния ролловера меняется только позиция единственного фонового изображения. a { background-image: url(A_rollover_bg.png); background-repeat: no-repeat; display: block; min-height: 27px; padding-top: 4px; padding-left: 35px; font-size: 16px; text-decoration: none; } a:visited { background-position: 0 -81px; } a:hover { background-position: 0 -54px; text-decoration: underline; } a:active { background-position: 0 -27px; } div { width: 230px; } ...
Для гиперссылок в данном примере определено единственное фоновое изображение. Четырём различным состояниям, определённым для гиперссылки (link, visited, hover и active), которым в CSS 2 соответствуют псевдоклассы, назначены разные позиции этого изображения (background-position).
Рис. 8.6. Использование изображений-ролловеров в меню Упражнения. Что будет, если текст ссылок сделать существенно длиннее? А если убрать указание ширины контейнера меню? Измените ассоциации всех состояний ссылки с изображениями (произвольно). Описанный приём имеет более и широкое применение: множество мелких изображений (маркеров, пиктограмм и т.п.) обычно рационально заменить одним составным, регулируя отображаемую часть средствами позиционирования фоновых изображений. Это сокращает число запросов к веб-серверу при загрузке документа.
Атрибуты ismap и usemap Сообщают браузеру, что изображение представляет собой "навигационную карту", содержащую одну или несколько гиперссылок, которые пользователь может выбирать мышью. Атрибут ismap указывает на серверную навигационную карту и может определяться только в элементе <а>: <а href="images/map2.aspx"> а> Браузер автоматически посылает серверу координаты мыши относительно левого верхнего угла изображения, когда пользователь щелкает где-то на изображенииismap. Специальная программа на сервере может затем употребить эти координаты при создании ответа.
Атрибут usemap обеспечивает механизм клиентской навигационной карты. В этом случае браузер на компьютере пользователя преобразует координаты щелчка на изображении в некоторое действие, например, загрузку и отображение другого документа. <map name="map1"> <area shape="rect" coords="13,8,87,71" href="http://www.w3schools.com/html/html_intro.asp" title="HTML page" alt="HTML page" /> Листинг 8.6. Клиентская навигационная карта (html, txt)
Рис. 8.7. Клиентская навигационная карта Упражнение. Создайте ещё две области в навигационной карте - они должны ссылаться на страницы http://www.w3schools.com/TAGS/tag_form.asp и http://www.w3schools.com/JS/default.asp. Пусть одна из них будет круглой.
Вопросы 1. Какой элемент используется для вставки изображения в документ? Какие атрибуты должен иметь этот элемент? 2. Какие свойства позволяют указать или ограничить размеры изображения? 3. Как достигается обтекание изображений текстом? 4. Какие свойства определяют фоновое изображение элемента? 5. Для чего используются ролловеры и как они создаются при помощи фоновых изображений?
Элементы colgroup и col Атрибуты colspan и rowspan
Динамическое создание таблиц Вопросы
Таблица, как правило, представляет собой довольно большой объём структурированной информации. В HTML-разметке объём ещё и увеличивается, поскольку каждая строка и каждая ячейка представляет собой HTML-элемент с открывающим и закрывающим тэгами. Вообще говоря, для создания HTML-таблиц желательно использовать WYSIWYGредактор (либо генерировать таблицу программно). Во всяком случае, для того, чтобы уметь использовать все полезные возможности таблиц, следует ознакомиться со стилями, применимыми к таблице и составляющим её элементам. В этом заключается задача данной лекции.
Минимальная структура. Заголовок и колонтитулы Структура минимальной таблицы показана на рис. 9.1. Диаграмму в этих обозначениях (использована нотация UML) следует понимать так: каждой таблице может принадлежать неограниченное количество строк (но как минимум одна). Каждой строке может принадлежать неограниченное количество ячеек (также не меньше одной). Ячейка может быть заголовочной - такую ячейку браузер выделяет полужирным начертанием. Внутри же ячейки (как обычной, так и заголовочной) может быть помещено всё то же, что и в документе - текст, изображения, формы и даже другие таблицы. Закрашенный ромб на линии связи означает "композиция", или "безраздельная принадлежность", что позволяет отличать композитную структуру (которой является и таблица HTML) от набора взаимно-информированных сущностей.
Листинг 9.1. Таблица минимальной структуры (html, txt)
Рис. 9.2. Таблица минимальной структуры Упражнения. Увеличьте толщину линий сетки и сделайте их двойными (double). Увеличьте поля ячеек. Добавьте столбец "Имя". Как видно из примера, в отсутствие стилевых определений браузер отображает таблицу без границ между ячейками. Очевидно, свойство border, будучи применённым к ячейке таблицы (т.е. к элементу td), создаст эти границы, а свойство padding добавит внутреннее поле. Несколько менее очевиден смысл свойства border-collapse: оно может принимать два значения - separate (по умолчанию) и collapse. Если выбрано значение separate (или не указано ничего), то между ячейками добавляется пустое пространство (при помощи свойства margin этого эффекта добиться не удастся). Если выбрано collapse, то таблица принимает более привычный вид.
К ячейкам (td и th) применимо большинство обычных стилевых правил, включая цвет, фон, выравнивание текста и т.п. Для содержимого ячейки также представляет интерес его вертикальное выравнивание - для этого определено CSS-свойство vertical-align, принимающее ряд значений, включая middle(середина - по умолчанию), top (верх) и bottom (низ). Этому CSS-свойству эквивалентен HTML-атрибут valign. Упражнения. Уберите стилевое правило border-collapse. Измените цвет фона ячеек. Сделайте ячейки, содержащие фамилии, заголовочными. Почему пропали рамки и как их вернуть? В варианте примера с внешней границей попробуйте следующие значения свойства border-style: solid, none, groove, double, ridge, inset, outset. Уберите css-объявление толщины границы ячейки. Почему границы стали толще?
Элемент caption Как правило, у таблицы имеется заголовок, и этот элемент специально предназначен для описания заголовка таблицы. Обычно его размещают сразу после тэга
. Если к элементу caption применить атрибут align="bottom", то он отобразится под таблицей. Как и ячейка, заголовок не имеет ограничений на содержимое. Упражнение. Добавьте заголовок к таблице в предыдущем примере. Установите для заголовка (создав правило CSS) полужирное начертание и отступ снизу.
Элементы thead, tbody и tfoot Обычно одна или несколько строк вверху таблицы содержит заголовки столбцов, образуя верхний колонтитул таблицы. Отличие верхнего колонтитула от остальных строк таблицы заключается, во-первых, в том, что он может каким-либо образом выделяться. Во-вторых, при распечатке длинных таблиц колонтитул должен появляться на каждой странице. HTML 4 предоставляет элемент thead для разметки верхнего колонтитула таблицы, и, поскольку он имеет как физический смысл (влияет на внешний вид), так и логический (влияет на понимание, а также на невизуальные методы воспроизведения), то рекомендуется его всегда использовать. Аналогичный, но менее важный элемент - tfoot - нижний колонтитул таблицы, т.е. группа строк в её нижней части. Элемент tbody объединяет строки в группы - они могут быть отделены друг от друга линейками специальной толщины. Где и в каком количестве могут содержаться эти элементы - показано на рис. 9.2:
Листинг 9.2. Таблица с колонтитулами и разделами (html, txt)
Рис. 9.4. Таблица с колонтитулами и разделами Упражнение. Откройте пример в новом окне браузера и из меню Файл выберите команду Предварительный просмотр. Перейдите ко второй странице и убедитесь, что на ней повторяются оба колонтитула (это должно работать, по крайней мере, в браузерах Windows Explorer и Mozilla Firefox).
Группы столбцов. Объединение столбцов и строк Элементы colgroup и col
Предназначены для того, чтобы назначать свойства столбцам или группам столбцов. Вообще, таблица задаётся набором строк, но работа со столбцами часто бывает необходима - например, для задания ширины или фонового цвета столбца - и поэтому HTML предоставляет эти два специальных элемента. Для того чтобы назначить свойства всем ячейкам одного столбца, используйте элемент col. Этот элемент может появляться только в элементе colgroup, а colgroup - только вtable:
... Если же одинаковые свойства нужно применить к нескольким подряд расположенным столбцам, то их можно присвоить элементу colgroup, тем самым немного сократив запись:
Что равносильно следующей записи:
Как видите, число столбцов в группе задаётся либо их явным перечислением (обычно это делается в том случае, если некоторые из них нуждаются в дополнительных атрибутах), либо указанием их количества в значении атрибута span. .graycol { background: #eee; } .widecol { width: 200px; } ...
например, для задания ширины или фонового цвета столбца
для этого HTML предоставляет элементы colgroup и col
Листинг 9.3. Применение элементов colgroup и col (html, txt)
Рис. 9.5. Применение элементов colgroup и col Упражнение. Примените к первым трём столбцам серый фон, а к последним - ширину 150 пикселей.
Атрибуты colspan и rowspan Обычно в каждой строке таблицы количество ячеек одинаково. Если их окажется меньше, то браузер создаст пустые ячейки вместо недостающих; если больше - лишние будут выступать за границы таблицы. В тех случаях, когда нужно объединить горизонтальную группу ячеек, пользуются атрибутом colspan:
Браузер создаст ячейку, занимающую то же пространство по горизонтали, как указанное количество ячеек в строках, расположенных выше или ниже. Аналогичным образом объединяется и вертикальная группа ячеек:
В обоих случаях, если значения атрибутов слишком большие (требуется объединить больше ячеек, чем их реально существует), то браузер объединит столько ячеек, сколько возможно, не создавая новых.
colspan="2"
colspan="3"
rowspan="2"
rowspan="2" colspan="2"
rowspan="3"
Листинг 9.4. Применение атрибутов colspan, rowspan и valign (html, txt)
Рис. 9.6. Применение атрибутов colspan, rowspan и valign Упражнение. Сделайте в таблице объединения как на рис. 7
Динамическое создание таблиц Чаще всего таблицы создаются не вручную, а программно. В наиболее распространённом случае таблица строится на основе результатов запроса к базе данных - это делается на стороне сервера посредством таких технологий как PHP, ASP.NET, JSP и т.п. Иногда бывает удобно также построить таблицу на стороне клиента из каких-нибудь "подручных" данных - в таком случае в роли "строителя" выступает программа на языке Javascript. Этот язык является столь же неотъемлемой частью вебтехнологий, как HTML и CSS, и о нём речь подробно пойдёт в отдельной лекции. Однако, забегая немного вперёд, рассмотрим небольшой пример формирования таблицы при помощи Javascript - пусть это будет таблица умножения однозначных чисел. Идея заключается в следующем: парсер браузера (подпрограмма, отвечающая за анализ кода), прочитав в HTML-коде элемент table (равно как и любой другой), создаёт в оперативной памяти объект, моделирующий таблицу. Этот объект включает в себя всё содержимое таблицы (атрибуты и вложенные элементы), а также предоставляет ряд методов для работы с объектом таблицы: Методы, применимые к table: • • • • • •
createCaption() - создать элемент caption deleteCaption() - удалить элемент caption createTHead() - создать элемент thead deleteTHead() - удалить элемент thead createTFoot() - создать элемент tfoot deleteTFoot() - удалить элемент tfoot
Методы, применимые к table, thead, tbody и tfoot: • • •
insertRow(index) - добавить строку в указанное место deleteRow(index) - удалить строку с указанным номером moveRow(fromIndex, toIndex) - переместить строку
insertCell(index) - добавить ячейку в указанное место deleteCell(index) - удалить ячейку с указанным номером
Методы, имена которых начинаются на create и insert возвращают ссылку на созданный объект. Методы insertRow(index) и insertCell(index) позволяют в качестве номера передать число -1, и в этом случае элемент будет вставлен в конец. Все эти методы можно вызвать в коде сценария на Javascript. Также полезно знать о некоторых свойствах, предоставляемый объектной моделью таблицы: Свойства объекта table: • • • •
tHead tBodies[] tFoot rows[] - также применимо к thead, tbody и tfoot.
var i = 2; /* повторяем для i от 2 до 9 */ do { /* добавляем в строку заголовка ячейку с числом i */ head_row.insertCell(-1).innerHTML = i; /* добавляем строку в тело таблицы */ var row = table.tBodies[0].insertRow(-1); /* добавляем к этой строке ячейку с числом i */ row.insertCell(-1).innerHTML = i; j = 2; /* повторяем для j от 2 до 9 */ do { /* добавляем к строке ячейку с числом i*j */ row.insertCell(-1).innerHTML = i * j; /* увеличиваем значение j */ j++; } while (j <= 9); /* увеличиваем значение i */ i++; } while (i <= 9); Листинг 9.5. Динамически созданная таблица (html, txt)
Рис. 9.8. Динамически созданная таблица Рассмотрим этот пример. С точки зрения структуры HTML-документа, в нём имеется два элемента: таблица MyTable и элемент script. Браузер, загрузив элементscript, выполняет содержащуюся в нём программу (хотя язык скрипта и необходимо указывать в атрибуте type, но единственным общепринятым языком скриптов для всех браузеров является именно Javascript). Программа формирует таблицу, ссылаясь на неё по имени table и, причём ссылка получается следующим образом:
var table = document.getElementById('MyTable'); Функция getElementById делает именно то, что говорит дословный перевод её названия: выдатьЭлементПоИд, т.е. найти в документе элемент со значением атрибута id равным требуемому и выдать ссылку на него. Свойство innerHTML позволяет задать разметку для содержимого любого контейнера (за исключением фреймов). Задавая его для ячейки таблицы, мы тем самым помещаем в эту ячейку текст (в принципе, можно поместить структуру любой сложности), и этот текст сразу же появляется в таблице в окне браузера. Что касается формирования данного примера, то следует рассмотреть несколько ключевых моментов. Описание переменной: var table = ...; Не будем здесь повторять общий курс информатики и объяснять, что такое переменная - достаточно сказать, что с переменными Javascript можно работать в основном так же, как и в других языках. Специфика в том, что, хотя переменная Javascript обычно принимает значение определённого типа (число, строка, объект и т.п.), сама переменная не типизирована: в неё всегда можно записать значение другого типа. Поэтому при описании переменных тип не указывается, в отличие, например, от Паскаля и Си. Тип значения переменной определяется исходя из выражения, при вычислении которого это значение вырабатывается: var s = "..."; //строка var i = 2;//число Операции со значениями: числа, естественно, можно складывать, умножать, вычитать и делить. Строки тоже можно складывать - сложение строк имеет смысл склейки: 2 + 3 //результат: 5 '2' + '3' //результат: '23' Инкремент: i++; //число, хранящееся в переменной i, увеличится на 1 Цикл: do { //тело цикла } while(/*условие продолжения цикла*/); Упражнение. Проанализируйте код скрипта с учётом рассмотренных моментов. Нетрудно превратить таблицу умножения, например, в таблицу деления - для этого достаточно заменить выражение i*j на i/j. Правда, красоту полученной таблицы нарушает разница в количестве знаков после запятой у значений, являющихся периодическими и непериодическими дробями. Воспользуемся методом округления: (i/j).toFixed(2) - это означает: число (i/j) следует округлить до двух знаков после запятой.
Какие элементы необходимо должны присутствовать в таблице? Каково назначение колонтитулов таблицы? Как и с какой целью столбцы объединяются в группы? Какие атрибуты используются для объединения ячеек по горизонтали и вертикали? 5. Какие манипуляции с содержимым таблицы можно производить при помощи методов и свойств объектной модели таблицы?
10. Лекция: Табличная и бестабличная вёрстка Макет страницы. Колонки, колонтитул, подвал. Формирование макета средствами HTMLтаблиц и правил CSS Содержание • • • • •
Табличная вёрстка CSS-вёрстка. Макет с одной колонкой CSS-вёрстка. Макет с двумя колонками CSS-вёрстка. Макет с тремя колонками. Асимметричный макет Вопросы
Задача вёрстки HTML-страниц появилась раньше, чем язык CSS, поэтому у неё давно имеется решение, не основанное на стилях. Любой макет страницы можно представить как таблицу, ячейки которой имеют требуемые размеры, позиции, оформление и содержание. Метод вёрстки, основанный на таблицах, совершенно универсален, достаточно прямолинеен и прост, он влечёт за собой сравнительно немного трудностей, связанных с кросс-браузерной совместимостью. Большой недостаток всего один: этот метод не даёт никаких средств для поддержки изменчивости дизайна, т.е. смены оформления макета. При табличной вёрсткеоформление неразрывно связано с содержанием документа. Этих недостатков лишён метод дизайна, основанный на методах позиционирования CSS, которые были рассмотрены в"Позиционирование средствами CSS"соответствующей лекции. Однако средства CSS-вёрстки несколько менее очевидны для понимания и требуют большей осторожности по отношению к специфике разных браузеров.
Табличная вёрстка Рассмотрим сначала пример табличной вёрстки, демонстрирующий основные приёмы разметки - объединение ячеек, установку границ и вертикальное выравнивание.
Листинг 10.1. Макет страницы, построенный как таблица (html, txt)
Рис. 10.1. Макет страницы, построенный как таблица Упражнение. Текст верхнего колонтитула выровняйте по центру, навигацию перенесите в низ страницы, а ссылки в меню выровняйте по верхнему краю. Введите какой-нибудь текст в правую (пустую) колонку. Очевидно, что хотя стили в рассмотренном примере и играют существенную роль, но вёрсткой всецело управляет таблица, и нельзя изменить оформления макета, не затронув этой таблицы. Такой способ вёрстки на сегодняшний день считается устаревшим (хотя и может применяться в пределах отдельных блоков).
CSS-вёрстка. Макет с одной колонкой Перейдём к рассмотрению CSS-вёрстки, начиная с простейшего одноколоночного макета. В этом случае достаточно применить горизонтальное центрирование к
единственной колонке (которая обычно представлена в разметке секцией). Вообще говоря, центрирование макета необязательно, но в большинстве примеров данной лекции оно осуществляется (отказаться от него всегда легко). В примерах рассматриваются два типа разметки — с фиксированной и непостоянной шириной — каждый из которых имеет свои плюсы и минусы. Дизайн с фиксированной шириной гарантирует то, что разметка выглядит неизменно при различных размерах мониторов. Однако на очень маленьком мониторе посетителю, возможно, придется горизонтально прокручивать страницу, чтобы просмотреть все содержимое. А на действительно широком мониторе макет с постоянной шириной будет выглядеть затерянной узкой полоской. Разметки с непостоянной шириной решают эти проблемы, но у них также есть свои собственные ограничения. На маленьком экране свободная разметка может настолько сжаться, что весь дизайн развалится, а при очень широком экране растянется так, что посетителям придётся читать ненормально длинные строки текста. Есть CSS-свойства, которые предусмотрены для того, чтобы решить эту проблему: minwidth, min-height, max-width и max-height. Свойства min- указывают браузеру сделать элемент, по крайней мере, таким же широким или высоким, как указанное значение. Вы можете применить свойствоminwidth к элементу body, чтобы управлять всей шириной содержимого страницы. Если посетитель расширит окно своего браузера до 1000 пикселов, содержимое страницы растянется так, что будет соответствовать всему доступному пространству. Однако если он сделает окно шириной 500 пикселов, то содержимое останется 760 пикселов в ширину, а браузер добавит горизонтальные полосы прокрутки. Свойство minheight делает то же самое, но для высоты документа. Свойства max- задают максимальные размеры. С ними вы будете уверены, что ваши страницы не станут слишком широкими, а значит, непригодными для чтения. Комбинируя перечисленные свойства, вы можете создать стиль, который изменяет размеры элемента в пределах установленных значений, так что дизайн никогда не станет слишком маленьким или слишком большим. Internet Explorer 6 и ниже полностью игнорирует эти свойства. #frame { width: 70%; min-width: 400px; margin-left: auto; margin-right: auto; background-color: #ddd; padding: 5px; } ...
Заголовок страницы
В случае одноколоночного макета достаточно применить горизонтальное центрирование к единственной колонке (которая обычно представлена в разметке секцией). Дизайн с фиксированной шириной гарантирует то, что разметка выглядит неизменно при различных размерах мониторов. Однако на очень маленьком мониторе посетителю,
возможно, придется горизонтально прокручивать страницу, чтобы просмотреть все содержимое. А на действительно широком мониторе макет с постоянной шириной будет выглядеть затерянной узкой полоской.
Разметки с непостоянной шириной решают эти проблемы, но у них также есть свои собственные ограничения. На маленьком экране свободная разметка может настолько сжаться, что весь дизайн развалится, а при очень широком экране растянется так, что посетителям придётся читать ненормально длинные строки текста. Есть CSS-свойства, которые предусмотрены для того, чтобы решить эту проблему: min-width, min-height, max-width и max-height.
Листинг 10.2. Варианты вёрстки одноколоночного макета при помощи CSS (html, txt)
Рис. 10.2. Макет с одной колонкой непостоянной ширины Упражнения. Поочерёдно откройте оба варианта данного примера в новом окне и, изменяя ширину окна браузера, проследите за поведением макета. Добавьте к макету нижний колонтитул с тёмно-серым фоном.
CSS-вёрстка. Макет с двумя колонками Переходя к большему числу колонок, будем применять позиционирование на основе плавающих элементов, при котором ширина колонок также может быть фиксированной или непостоянной. Следует очень внимательно следить за тем, чтобы суммарная ширина всех колонок не превысила 100% (при непостоянной ширине) или ширины общего контейнера (при фиксированной ширине). Иначе последняя колонка переместится вниз. Подсчитывая суммарную ширину, принимайте в расчёт значение свойства width колонки, а также padding и border и, если есть, margin. Разумеется, поля, границы и отступы учитываются с обеих сторон. С этим подсчётом связано следующее затруднение: как сложить, например, 50% и 2px? Решить его можно двумя способами: или пользоваться везде только одним способом измерения (пикселы либо проценты), или же оценить максимально возможную процентную долю пиксела, ограничив ширину макета. Например, если для глобального контейнера, содержащего весь макет, указано свойство min-width: 400px , то можно быть уверенным, что 4px не превосходят одного процента ширины макета. В остальном идея проста: колонки снабжаются свойством float:left и указанием ширины, а также отступа и поля. При двух- и трёхколоночном макете необязательно делать плавающей центральную колонку (иногда это нежелательно) - вместо этого ей можно задать достаточные отступы слева и справа, а крайние колонки сделать плавающими - одну с float:left, а другую с float:right. Задавая колонкам фоновые цвета, вы обнаружите, что, когда в колонке мало содержимого, заполненный фоном блок смотрится не вполне эстетично. Предпочтительнее, чтобы он доходил внизу до нижнего колонтитула (или края страницы). Чтобы добиться этого эффекта, не обойтись без специального трюка: например, заполнить страницу вертикально фоновым изображением, имеющим высоту 1 пиксел и повторяющим в горизонтальном направлении раскраску колонок. Понятно, что на самом деле колонки останутся той же высоты (которая зависит от содержимого и полей), но внешне будет казаться, что они "достают" до нижнего колонтитула. #frame { width: 85%; min-width: 400px; margin: 0 auto; } #col1 { float: left; width: 66%; padding-right: 4px; margin-right: 4px; border-right: 1px solid black; } #col2 { float: left; width: 30%; padding: 4px; background-color: #ddd; } #footer { clear: both; border-top: 1px solid black; padding-top: 5px; margin-top: 5px; } ...
} Пример 10.4. Варианты вёрстки двухколоночного макета при помощи CSS. Макет фиксированной ширины - заполнение фоном всей высоты меньшего столбца (html, txt)
с
2
столбцами
Рис. 10.4. Макет с 2 столбцами фиксированной ширины - заполнение фоном всей высоты меньшего столбца Упражнение. Как поменять местами левую и правую колонки? Как добавить верхний колонтитул?
CSS-вёрстка. Макет с тремя колонками. Асимметричный макет Аналогичным образом строится и трёхколоночный макет. body { background-color: #bbb; } #frame { width: 760px; margin: 0 auto; background-color: #eee; } #header { border-bottom: 1px solid black; padding: 5px; text-align: center; } #col1 { float: left; width: 200px; padding-left: 10px;
Рис. 10.5. Макет с 3 колонками с верхним колонтитулом Необязательно, чтобы макет страницы представлял собой набор колонок, выстроенных в один ряд. Нередко встречается и "неправильный" дизайн - с произвольным размещением элементов - особенно, если на странице совсем немного содержимого. Для его создания легче воспользоваться WYSIWYG-редактором, в котором вы сможете создать набор блоков с абсолютным позиционированием и координатами границ, выраженными в пикселах или процентах. #main { bottom: 10%; left: 5%; width: 40%; } #title { top: 50%; left: 50%; width: auto; } #title h1 { margin: 0; } #block2 { top: 2%; right: 2%; width: 25%; } div:hover { z-index: 1; } ...
<strong>Центральный блок имеет ширину 40% (от ширины страницы) и позиционирован абсолютно следующим образом: bottom: 10%; left: 5%;.
"Неправильный" дизайн - с произвольным размещением элементов используется
обычно когда на странице совсем немного содержимого.
Заголовок
<strong>Блок 2 позиционирован при помощи свойств top: 2%; right: 2%;
Листинг 10.6. Асимметричный макет с непостоянной шириной элементов (html, txt)
Рис. 10.6. Асимметричный макет с непостоянной шириной элементов
Вопросы 1. В чём заключаются преимущества и недостатки табличной вёрстки макета страницы? 2. В чём заключаются преимущества и недостатки вёрстки с фиксированной и непостоянной шириной колонок? 3. Как гарантировать, что суммарная ширина элементов, размеры которых измеряются как в пикселах, так и в процентах, не превосходит ширины окна? 4. Какой приём используется для заполнения фоном всей высоты колонки с небольшим количеством содержимого? 5. Какую HTML-структуру имеет многоколоночный макет?
11. Лабораторная работа: Создание макета страницы средствами правил CSS Цель. Практическое освоение основных приемов верстки HTML-страницы с несколькими разделами. Содержание •
Часть 1. Создание трехколоночного макета с колонтитулами
o o o •
1. Создание документа и пяти секций. 2. Позиционирование блочных элементов 3. Добавление полей и центрирование.
Часть 2. Усовершенствование вида макета
o o o o o
1. Верхний колонтитул 2. Основной раздел. 3. Правая панель. 4. Нижний колонтитул. 5. "Ложные" столбцы.
Часть 1. Создание трехколоночного макета с колонтитулами
1. Создание документа и пяти секций. Запустите Visual Web Developer и создайте новую HTML-страницу. Сразу сохраните ее в своей папке под именем Lab11.htm. Макет будет состоять из трех колонок и двух колонтитулов. Как правило, для верстки макета оперируют секциями (элементами div). Создайте в теле документа пять элементов - в качестве левой панели используйте готовое вертикальное меню из лабораторной работы 2, а остальные элементы - секции: • • • • •
верхний колонтитул с заголовком и изображением - div id="header"; левая панель - навигационное меню - ul id="MainMenu"; основное содержимое страницы - div id="main"; правая информационная панель - div id="right"; нижний колонтитул - div id="footer".
В header вставьте короткий заголовок первого уровня (текст, как обычно, произвольный). Навигационную панель (ее вертикальный вариант) полностью можете скопировать из второй работы (не забудьте скопировать и стили). В основной раздел main вставьте заголовок первого уровня и пять абзацев с произвольным содержимым. В правой панели также вставьте несколько недлинных абзацев с заголовками. В нижнем колонтитуле напишите пока просто "footer" - кстати, рекомендуем в начало текста каждой секции временно вставить обозначение ее назначения - чтобы в дальнейшем было легче понять, правильно ли они разместились на странице.
2. Позиционирование блочных элементов Элементы header, main и right должны размещаться как три вертикальные колонки, делящие между собой ширину страницы. Для этого проще всего применить позиционирование на основе плавающих элементов. Создайте для каждого из этих трех элементов правила, основанные на селекторах идентификаторов, определяющие для них фиксированную ширину в пикселах (в сумме - 700-780px) и свойство float: left; Для нижнего колонтитула установите свойство clear: both, чтобы он "не плавал". Если в меню у вас текст имеет белый цвет, то, чтобы его увидеть, задайте какой-либо фоновый цвет всему меню.
3. Добавление полей и центрирование. Определите значения свойства padding для тех элементов макета, которые имеют слишком плотные стыки. Также задайте фоновые цвета. Отцентруйте страницу, определив для элемента body автоматические значения левого и правого отступа, а также указав ширину. При расчете ширины будьте внимательны, иначе колонтитулы будут выступать по горизонтали за пределы области колонок. Ширина колонок складывается из значений свойства width, указанных для них, а также удвоенных padding и border.
Рис. 11.1. Заготовка макета с плавающими колонками, верхним колонтитулом и панелью навигации Верхний колонтитул имеет отступы сверху и снизу - точнее, их производит заголовок, находящийся в нем. Добавьте правило, обнуляющее отступы заголовка в секции header: #header h1 { margin: 0; padding: 10px; }
1. Верхний колонтитул Добавьте фоновое изображение - можете использовать файл либо другое на ваш выбор.
2. Основной раздел. Цвета заголовков в этом разделе (и в остальных) приведите к единой цветовой гамме. Между абзацами вставьте горизонтальные линии (элементы hr). Добавьте пространства между абзацами (используя свойства margin-top и margin-bottom). Горизонтальным линиям назначьте такой же цвет, как у заголовков, и центрируйте их, задав ширину 50% и автоматические отступы слева и справа. Создайте правила для первых букв абзаца, изменив их цвет (под цвет заголовков), размер (раза в 3 больше) и добавив свойство float: left.
3. Правая панель. Заголовки уменьшите, выровняйте по центру и уберите вертикальные отступы. У абзацев также уменьшите вертикальные отступы.
4. Нижний колонтитул. Вставьте в него элемент логического форматирования address, внутри которого поместите ссылку на некоторый почтовый адрес: Webmaster Выделите адрес полужирным начертанием и светло-серым цветом: #footer a { font-weight: bold; color: #ddd; }
5. "Ложные" столбцы. Чтобы высота левой и правой колонок была не меньше, чем у центральной, придется применить специальный трюк: заполнить страницу вертикально фоновым изображением, имеющим высоту 1 пиксел и повторяющим в горизонтальном направлении раскраску колонок. Понятно, что на самом деле колонки останутся той же высоты (которая зависит от содержимого и полей), но внешне будет казаться, что они "достают" до нижнего колонтитула. Сделайте скриншот экрана (открыв браузер и нажав Alt-PrintScreen), запустите любой редактор рисунков (например, Paint) и вставьте скриншот из буфера в редактор. Вырежьте тонкую полоску высотой 1px и шириной, равной ширине элемента body вашей страницы. Сохраните ее в файл с названием, например,background.png. Создайте еще одну секцию с id="Wrapper" и поместите в нее все, что находится внутри элемента body. В определение стиля секции Wrapper добавьте файлbackground.png в
12. Лекция: Сценарии Javascript Содержание • • • •
Характеристики языка Javascript Вставка сценария в HTML-документ Переменные и типы данных Операторы и управляющие структуры
o o o o
Арифметические операторы Логические операторы Управляющие структуры Встроенные объекты Javascript
•
Создание пользовательских объектов
•
Пример: карточная игра Blackjack
o o o •
Внешние объекты Правила игры Разработка объектной модели
Вопросы
Первоначально разработанный в 1995 году Бренданом Эйком (Brendan Eich), работавшим в Netscape, в сотрудничестве с Sun Microsystems, язык сценариев Javascript является объектно-ориентированным языком. Изначально Javascript предназначался для разработки клиентских приложений в веб-браузере с целью расширения пользовательского интерфейса и разработки динамических веб-страниц. В 1997 году язык был стандартизирован Европейской ассоциацией производителей компьютеров (European Computer Manufacturers Association, ECMA) под названием ECMAScript (ECMA-262). Internet Explorer, начиная с версии 3.0 (1996), поддерживает диалект ECMAScript, названный JScript. Как любой живой язык, JScript развивался, и Internet Explorer 8.0 использует версию языка JScript 5.8, основанную на 3 издании стандарта ECMA-262. В целом, диалекты ECMAScript достаточно близки, по этой причине Javascript и JScript часто считаются синонимами. Несмотря на сходство названий, Javascript не является родственником Java, оба языка наследовали свой синтаксис от языка C.
Характеристики языка Javascript Javascript поддерживает синтаксис структурного программирования языка C, включая ветвление (инструкции if…, if…else…и switch) и циклы (инструкции for и while ). Типы данных в Javascript связаны со значениями, а не с переменными. Это означает, что любой переменной может быть присвоено значение одного типа (например, число), затем другого типа (например, строка). Такое поведение иногда называют также нестрогой типизацией. Javascript почти полностью построен как объектный язык. Фактически, объекты Javascript – это ассоциативные массивы; запись obj.x = 10 эквивалентнаobj["x"] = 10 и obj[0] = 10 (полагая, что x является первым по счету свойством объекта obj). Свойства объекта и их значения могут добавляться, изменяться и удаляться динамически. Функция eval() позволяет выполнять инструкции, заданные в виде строки.
Функции в Javascript являются объектами первого класса, то есть могут присваиваться переменным, передаваться в другие функции в качестве аргумента и возвращаться функциями. Внутренние функции (определенные внутри других функций) создаются, когда выполняется внешняя функция, и переменные внешней функции доступны для внутренней даже когда внешняя функция завершила работу. Javascript не использует понятия классов. Наследование осуществляется через механизм прототипов (prototype), то есть клонирования существующих объектов. Функции могут выступать в качестве конструкторов объектов. В этом случае ключевое слово this относится к создаваемому объекту. В Javascript нет различий между определением функции и метода. Различие возникает, когда функция вызывается как метод объекта. В этом случае ключевое слово this относится к объекту, чьим методом оказывается функция. Функции в Javascript могут принимать произвольное число аргументов, в том числе и не описанные при определении функции. Доступ к ним осуществляется как через формальные параметры функции, так и через свойство arguments функции.
Вставка сценария в HTML-документ Сценарий Javascript вставляется в HTML-документ при помощи тэга script. <script type="text/javascript"> document.write('Hello from Javascript'); Сценарий может также храниться в отдельном файле. <script type="text/javascript" src="myscript.js"> Атрибут language элемента script описывает используемый язык сценариев (например, Javascript). Этот атрибут считается устаревшим и не рекомендуется к использованию. Элементы script могут присутствовать элементов head и body HTML-документа.
в
неограниченном
числе
внутри
Переменные и типы данных Javascript во многом наследовал синтаксис языка C, а это значит, что строчные и заглавные буквы в идентификаторах различаются. Нет необходимости специально объявлять переменные, хотя это является хорошей программистской практикой. Первое появление переменной автоматически является ее объявлением. Имя переменной должно начинаться с буквы или символа подчеркивания (_), последующими символами могут быть буквы, цифры и символ подчеркивания (_). Нельзя использовать в качестве имен переменных зарезервированные слова, такие как if, for, function, new. Для объявления переменной может использоваться необязательное слово var. Его использование обязательно только в том случае, если переменная объявляется внутри функции и пределом видимости этой переменной должна быть эта функция. Переменные, объявленные без использования var, являются глобальными. Примеры правильного объявления: var test; //объявление без присвоения. Значение переменной undefined
a = 2; var b2 = 3; sum_a_b2 = a + b2; Примеры недопустимых имен: var 3piglets // начинается с цифры var Smith&Wesson // символ & не допускается var for // for является зарезервированным словом В Javascript есть три простых типа данных: строка (String), число (Number) и логический тип (Boolean), два составных типа: объект (Object) и массив (Array) и два специальных типа: пустое значение (Null) и неопределенное значение (Undefined). Тип данных ассоциирован не с именем переменной, а с ее значением. Строковые данные – любая цепочка символов, заключенная в одиночные (') или двойные кавычки ("). Одиночные кавычки могут содержаться в строках, заключенных в двойные кавычки и наоборот. "простая строка" 'еще одна строка' "don't worry" Числовые данные подразделяются на целые и числа с плавающей запятой (фактически, точкой), но внутренним представлением данных всегда является число с плавающей запятой. Целые числа могут быть представлены в десятеричной, восьмеричной и шестнадцатеричной форме. Числа с плавающей запятой могут записываться в степенной форме. Число
Десятичное представление
Описание
0.0001, .0001, 0.0001 1e-4, 1.0e-4
Разные представления числа с плавающей запятой
125
125
Целое
0377
255
Восьмеричное представление целого
0378
378
Десятичное целое. Восьмеричное допускает лишь цифры от 0 до 7
0xff
255
Шестнадцатеричное представление
0x3e7
999
Шестнадцатеричное представление
00.001 0x0.001
-
Ошибка компиляции. шестнадцатеричные числа целыми
Данные логического (Boolean) типа значений: true (истина) или false (ложь).
принимают
представление
Восьмеричные и могут быть только
лишь
одно
из
двух
y = (x == 10); //истина, если x равно 10 Чаще всего логические данные или выражения, возвращающие логические данные, используются в управляющих структурах: if (x == 10) a = c; // выполняется, если x равно 10 else a = b; // выполняется в противном случае
В качестве логического может быть использовано любое выражение, например, число, строка, массив или объект, при этом, если значение равно 0, пустой строке, пустому (не содержащему элементов) массиву, пустому объекту (Null) или неопределенному значению (undefined), то условие оценивается как false (ложь), в противном случае как true (истина). Например, две следующие конструкции эквивалентны. if (x != 0)//если x не равен 0 a = 1; if (x) a = 1; Массив представляет собой данные, доступ к элементам которых осуществляется по индексу. Массивы в Javascript создаются следующим образом: var a = new Array();// создает новый пустой массив var b = new Array(N);//где N – положительное целое. //Создает массив из N пустых элементов var c = new Array(elem1, elem2 ...); //создает массив из перечисленных элементов. //Элементы должны существовать заранее. var d = [elem1, elem2 ...]; //создает массив из перечисленных элементов var e = [];// создает новый пустой массив Индексация массивов всегда начинается с нуля (0), то есть последний существующий элемент имеет индекс на 1 меньше длины массива. document.write(c[0]); //будет выведен первый элемент массива c a[0] = 1; // присвоение значения первому элементу массива a a[10] = 10; // присвоение значения одиннадцатому элементу массива a // элементы 1 – 9 заполняются пустыми значениями. // длина массива a.length равна 11 document.write(a[10]); // печатает 10 document.write(a[11]); //печатает пустую строку и не меняет длину массива Нет необходимости переопределять длину массива. Присвоение значения несуществующему элементу массива автоматически создает этот элемент (если его не было) и заполняет массив пустыми элементами между последним существовавшим и вновь добавленным элементом.
Операторы и управляющие структуры Javascript поддерживает арифметические, логические и битовые операторы и ряд вспомогательных операторов.
Арифметические операторы Операции сложения (+), вычитания (-), умножения (*) и деления (/) выполняются в общепринятой манере. x = ((1 + 2)*3 – 4)/5; // 1 Оператор деления с остатком (%) делит первое число на второе и возвращает остаток a = 9 % 4; // 1 b = 19 % 6.7; // 5.6
В Javascript нет операции целочисленного деления. Чтобы получить целое частное, следует отсечь десятичные знаки. dividend = 13; // делимое divisor = 5; // делитель quotient = parseInt(dividend / divisor); // частное (2) reminder = dividend % divisor; // остаток (3) Оператор плюс (+) требует некоторого дополнительного внимания. Помимо арифметического сложения этот оператор выполняет также конкатенацию (строковое слияние). Результат может иногда оказаться неожиданным (для начинающего разработчика). a = 1; b = '2'; c = a + b; // 12 Строковое слияние происходит всегда, когда хотя бы один из операндов – строка. Остальные арифметические операторы пытаются сначала преобразовать строку в число и только в случае неуспеха возвращают ошибку NaN (Not a Number). Арифметические операторы могут быть объединены с оператором присваивания (=), что является удобной сокращенной записью операций. a b c c
+= 3; // эквивалентно a = a + 3 /= 2; // b = b / 2 = 'Hello'; += ' world!'; // Hello world
Есть также три одноместных оператора: смены знака (-), инкремента (++) и декремента (--). x = -x; // смена знака x++; // эквивалентно x += 1 или x = x + 1 --x; // эквивалентно x -= 1 или x = x – 1 Операторы инкремента и декремента могут иметь префиксную (++x) и постфиксную (x++) формы. В префиксной форме переменная сначала изменяется, затемиспользуется, в постфиксной сначала используется, затем изменяется. var a, b, c, d; a = b = 2; // так можно, поскольку оператор присваивания возвращает значение c = ++a; // 3 d = b++; // 2
Логические операторы Операторы сравнения производят сравнение числовых или строковых операндов и возвращают логическое значение. При сравнении строки рассматриваются как цепочки 16-битных символов. Следует иметь в виду, что в таблицах символов заглавные буквы идут впереди строчных, таким образом "Я" оказывается меньше "автор". Для правильного алфавитного сравнения строки следует привести к верхнему или нижнему регистру. Операторы > (больше), < (меньше), >= (больше или равно), <= (меньше или равно): •
Если оба операнда – строки, выполняют строковое сравнение Если любой из операндов имеет значение NaN (Not возвращают false (ложь) -0 == +0 -∞ < -∞ < любое число +∞ > +∞ > любое число
a
Number),
Операторы == (равно), != (не равно): • • • • •
Если типы данных различны, пытаются привести их к строке, числу или логическому типу NaN != NaN -0 == +0 null == null, null == undefined 1 == '1', 1 == true, 0 == false, true != 'true'
Операторы сравнения на идентичность (===) и неидентичность (!==). Для идентичности операнды должны быть одного типа и указывать на один объект. Логическое отрицание (!) меняет истину на ложь и наоборот. Логическое И (&&) возвращает истину, только когда оба операнда истинны. Логическое ИЛИ (||)возвращает истину, только когда хотя бы один из операндов истина. "Тройной" условный оператор позволяет сократить запись при присваивании значения по условию: var x = 3; result = x % 2 == 0 ? "четное" : "нечетное"; //эквивалентно if (x % 2 == 0) result = "четное"; else result = "нечетное";
Управляющие структуры Ветвящиеся структуры, if, if…else и switch, позволяют программы в соответствии с проверяемым условием.
направить
выполнение
if (b != 0) c = a / b; //выполнить деление только если делитель не ноль if (x % 2 == 0) document.write(x + ' четное'); else document.write(x + ' нечетное'); var d = new Date(); // объект Date – текущая дата и время switch (d.getDay()) { case 0: document.write("Воскресенье"); break; //выход из переключателя. //Если опущен, будет выполнена и следующая инструкция case 1:
document.write("Понедельник"); break; case 2: document.write("Вторник"); break; case 3: document.write("Среда"); break; case 4: document.write("Четверг"); break; case 5: document.write("Пятница"); break; case 6: document.write("Суббота"); break; default: // выполняется, если не выполнено //ни одно из предыдущих условий document.write(d.getDay()); } Второй тип управляющих структур – циклы, то есть повторное выполнение некоторой инструкции или блока инструкций до тех пор, пока выполняется некоторое условие. В Javascript существуют четыре формы циклов: Цикл for управляется счетчиком. var a = []; // объявляем массив for (var i = 0; i < 10; i++) a[i] = i; // заполняем 10 элементов массива var sum = 0; for (var j = 0, N = a.length; j < N; j++) sum += a[j]; document.write('Сумма = ' + sum); Специальная форма for, for/in, удобна для перебора свойств объекта. var nav = window.navigator; // информация о браузере for (prop in nav) document.write(prop + ': ' + nav[prop] + ' \n'); // печатает построчно пары свойство: значение объекта. В цикле while условие проверяется перед началом каждого повтора. Если условие изначально ложно, цикл не будет выполнен. var x = 0; while (x != 4) {//цикл повторяется, пока условие истинно x = window.prompt('Сколько будет 2 * 2', x); //метод window.prompt открывает диалоговое окно с полем ввода, //куда нужно ввести ответ. } if (x == 4) window.alert("Правильно"); В цикле do…while условие проверяется в конце цикла, то есть цикл повторяется как минимум один раз. var x = 0; do { x = window.prompt('Сколько будет 2 * 2', x);
} while (x != 4); //цикл повторяется, пока условие истинно if (x == 4) window.alert("Правильно"); В некоторых случаях требуется выход из цикла или переход к началу цикла до завершения всего блока инструкций. Оператор break заканчивает выполнение цикла и передает управление первой инструкции после цикла. Оператор continue пропускает инструкции до конца блока и начинает новый повтор цикла. var x = 0; while (x != 4) { x = window.prompt("Сколько будет 2*2?", x); if (x == null)//пользователь нажал "Отмена" break; // выход из цикла if (Number(x) == x)// является ли x числом continue; // пропускаем остаток и начинаем новый повтор // с проверкой условия //сюда попадаем, только если введено не число window.alert("Вводите только числа"); } // конец цикла if (x == null) window.alert("Вы сдались"); else window.alert("Вы угадали");
Встроенные объекты Javascript Javascript поддерживает ряд собственных объектов, среди которых обратим внимание на следующие: Объект Object содержится во всех остальных объектах и обеспечивает их общую функциональность. Уже упомянутые числа, строки и массивы являются объектами Number, String и Array, соответственно, и каждый из этих объектов имеет свой набор свойств и методов. Объект Math открывает доступ к алгебраическим и тригонометрическим функциям. Объект Date предназначен для операций с датой и временем; при работе в браузере доступны лишь функции чтения данных, такие как getDate, getDay, но не setDate или setTime. Объект Global создается при запуске движка Javascript, его свойства, такие как Infinity(бесконечность), NaN (ошибка Not a Number) и undefined (неопределенная переменная), и методы доступны автоматически. var a = '3'; //строка var b = 4; //число var c = a + b; //34 – строковое слияние var d = parseFloat(a) + b; //7 //функция parseFloat – читать как число с плавающей запятой – //гарантирует, что строка, содержащая число, будет интерпретирована //как число var str = 'var x = 2 + 3;'; eval(str); document.write(x); //5 //функция eval выполняет код, заданный в виде строки, //которая может генерироваться динамически
Особое место занимает объект Function (функция). Функции в Javascript являются объектами первого класса, то есть могут присваиваться переменным, выступать аргументами других функций и быть результатом (возвращаемым) функций. В Javascript есть несколько вариантов синтаксиса создания функций. //классический синтаксис function a1(x, y) { return x + y; } //явное создание объекта Function var a2 = new Function('x', 'y', 'return x + y'); //обязательным является только последний аргумент – тело функции //еще один вариант var a3 = function(x, y) { return x + y; }; Независимо от способа задания функции ее вызов осуществляется одинаково и с одинаковым результатом. a = a1(3, 4); b = a2(3, 4); c = a3(3, 4); Функция как объект имеет собственные свойства function ArgTest(a, b) { var i, s = "Функция ArgTest ожидает "; //число аргументов при объявлении функции var expargs = ArgTest.length; //число аргументов при вызове функции var numargs = ArgTest.arguments.length; if (expargs < 2) s += expargs + " аргумент. "; else s += expargs + " аргумента. "; if (numargs == 1) s += " Получен 1 аргумент."; else s += "Получено " + numargs + " аргументов."; return (s); } Массив arguments содержит аргументы, отправленные в функцию при вызове, даже если они не были перечислены при объявлении функции. function sum() { var s = 0; for (var i = 0, n = arguments.length; i < n; i++) s += arguments[i]; return s; } document.write(sum(1, 2, 3, 4)); //10 Как было сказано, функции могут быть аргументами других функций. Например, метод sort объекта Array производит сортировку массива и может принимать в качестве аргумента функцию сравнения элементов массива. //создаем и заполняем массив 10 элементами var arr = [];
for (var i = 0; i < 10; i++) arr[i] = i; //сортируем массив по убыванию arr.sort(function(x, y) { return x < y ? 1 : -1; }); //функция сравнения принимает два аргумента и возвращает -1, //если первый элемент должен идти впереди второго, //и 1 в противном случае //перетасовываем массив, т.е. сортируем в произвольном порядке arr.sort(function() { return Math.random() < 0.5 ? 1 : -1; }); //от аргументов функции сравнения ничего не зависит, //поэтому они могут быть опущены. 1 и -1 возвращаются //в случайном порядке Функции могут вызываться из функций, в том числе из самих себя (рекурсия). Классический пример рекурсии – расчет факториала. function Factorial(N) { return N < 2 ? 1 : N * Factorial(N - 1); }
Создание пользовательских объектов Функции могут служить конструкторами пользовательских объектов. В этом случае ключевое слово this является ссылкой на вновь создаваемый объект. //конструктор объекта Окружность function Circle(x, y, r) { this.x = x; //x-координата центра this.y = y; //y-координата центра this.r = r; //радиус окружности } //создание объектов var circle1 = new Circle(1, 1, 2); var circle2 = new Circle(3, 3, 1); Свойство prototype функции-конструктора позволяет добавлять свойства и методы как к пользовательским, так и встроенным объектам. function getLength() { //this является ссылкой на объект, //в контексте которого осуществляется вызов return 2 * Math.PI * this.r; //длина окружности } //подключаем функцию к конструктору //обратите внимание на отсутствие скобок //без скобок присваивается объект-функция //со скобками – результат выполнения функции Circle.prototype.length = getLength; //Добавим еще один метод Circle.prototype.area = function() { return Math.PI * this.r * this.r; //площадь круга } document.write("circle1 имеет радиус " + circle1.r + ", длину " + circle1.length() +
" и площадь " + circle1.area()); Использование функции-конструктора позволяют создавать любое число объектов. Если требуется всего один объект, можно воспользоваться альтернативным синтаксисом. var uniqueObj = { prop1: 10, //определяем числовое свойство prop2: 'red', //определяем строковое свойство method1: function() { return 'Hello'; } //определяем метод };
Внешние объекты Internet Explorer и другие браузеры открывают доступ к собственной объектной модели через программный интерфейс приложения (Application Programming Interface, API), так что свойства, методы и события объектов браузера становятся доступны для Javascript.
Пример: карточная игра Blackjack В качестве примера разработаем карточную игру, известную под названием Blackjack, которая будет работать в веб-браузере.
Правила игры Игра ведется колодой карт из 52 листов, от двойки до туза в каждой из четырех мастей. Каждая карта имеет свою цену, в очках. (От двойки до десятки в соответствии со значением, картинки – 10, туз 11 или 1, в зависимости от набранных очков) В игре участвуют два игрока: собственно игрок и крупье. Цель игры - набрать больше очков, чем противник, но не более 21 (за исключением двух тузов). Игрок (человек) делает ставку в пределах своего баланса и берет карты по одной, пока не сочтет количество очков достаточным, после чего передает ход крупье. Крупье (компьютер) действует автоматически.
Разработка объектной модели Колода состоит из карт. Каждая карта характеризуется мастью, значением и числом очков. Кроме того, уместно привязать к карте ее картинку. Фактически, если перенумеровать все карты в колоде от 0 до 51, то все свойства карты можно рассчитать из ее порядкового номера. //конструктор карты function Card(n) { //вспомогательные массивы var suits = ['треф', 'бубен', 'червей', 'пик']; var names = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Валет', 'Дама', 'Король', 'Туз']; var values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]; //рассчитываем свойства карты по ее номеру this.suit = suits[parseInt(n / 13)]; //масть this.name = names[n % 13]; //название this.value = values[n % 13]; //очки //прикладываем картинку к карте - объект Image Веб браузера
this.img = new Image(); //рассчитываем имя файла и инициализируем загрузку файла, //полагая, что изображения хранятся в папке deck //и поименованы от 0.gif для двойки треф //до 51.gif для туза пик this.img.src = 'deck/' + n + '.gif'; //задаем дополнительные атрибуты изображения this.img.alt = this.toString(); this.img.className = 'Card'; } // переопределяем функцию toString Card.prototype.toString = function() { return this.name + ' ' + this.suit; } Колода – единичный объект. Создадим его для дальнейшего использования. var Deck = { cards: [], //собственно колода - массив карт, изначально пустой num: 0, // внутренний счетчик //колоду нужно инициализировать перед первым использованием init: function() { //заполняем массив for (var i = 0; i < 52; i++) //все данные карты рассчитываются по ее номеру this.cards[i] = new Card(i); }, //тасуем колоду, т.е. сортируем в случайном порядке shuffle: function() { this.cards.sort(function() { return (Math.random() < 0.5 ? 1 : -1); } ); this.num = 0; //инициализируем счетчик }, nextCard: function() { //возвращает верхнюю карту из колоды return this.cards[this.num++]; } }; В игре участвуют двое. Создадим конструктор для них. function Hand() { } // конструктор игрока необходим, даже пустой Hand.prototype = {//свойства и методы игрока balance: 1000, //начальная сумма currentBet: 0, //текущая ставка cards: [], //массив карт у игрока //Методы игрока init: function() {//сбросить карты this.cards = new Array(); }, bet: function() {//увеличиваем ставку this.balance += this.currentBet; if (this.currentBet == 0) this.currentBet = 10; //произвольная начальная ставка else this.currentBet *= 2; //удваиваем ставку
//ограничим ставку балансом игрока if (this.balance >= this.currentBet) this.balance -= this.currentBet; else { this.currentBet = this.balance; this.balance = 0 } //возвращаем значение для удобства использования return this.currentBet; }, nextCard: function() {//взять следующую карту var card = Deck.nextCard(); //следующая карта из колоды this.cards.push(card); //добавляем в конец массива //возвращаем значение для удобства использования return card; }, //подсчитываем очки на руке игрока calc: function() { var sum = 0; //сумма очков var aces = 0; // число тузов if (this.cards)//если массив карт не пустой for (var i in this.cards) { if (this.cards[i].value == 11) aces++; //найден туз //суммируем очки sum += this.cards[i].value; } //если на руке не более 2 карт, пересчет не нужен if (this.cards.length < 3) return sum; // в случае перебора считаем туза за 1 while (sum > 21 && aces > 0) { sum -= 10; aces--; } return sum; }, //сравнение двух игроков compare: function(anotherHand) { //результат: 1 - победил первый, //-1 - победил второй, 0 – ровно //подсчитываем очки первого игрока var a = this.calc(); if (a > 21 && this.cards.length > 2)//перебор у первого return -1; //подсчитываем очки второго игрока var b = anotherHand.calc(); if (b > 21 && anotherHand.cards.length > 2) // перебор у второго return 1; if (a == b)//ровно return 0; if (a == 22 && this.cards.length == 2) // у первого игрока Black Jack return 1; if (b == 22 && anotherHand.cards.length == 2) // у второго игрока Black Jack return -1; if (a > b)//У первого больше return 1; //остается единственный вариант - у второго больше return -1; } };
{ height: 30px; } Остается создать игроков, инициализировать колоду карт и обработать события нажатия на кнопки. //задаем функцию, выполняемую при загрузке страницы window.onload = function() { Deck.init(); //заполняем колоду картами player = new Hand(); //игрок объявлен глобально dealer = new Hand(); //крупье объявлен глобально //кнопки "Взять карту" и "крупье" изначально недоступны document.getElementById('btnRun').disabled = true; document.getElementById('btnFinish').disabled = true; //вспомогательная функция Show() определена ниже Show(); } //обрабатываем нажатие кнопки "увеличить ставку" function bet() { dealer.init(); //сбросить карты у крупье player.init(); //сбросить карты у игрока Deck.shuffle(); //перетасовать колоду //очищаем окно от карт и результата document.getElementById('player').innerHTML = ''; document.getElementById('dealer').innerHTML = ''; document.getElementById('result').innerHTML = ''; document.getElementById('sum').innerHTML = ''; if (player.bet()) { // нет необходимости писать if (player.bet() > 0) // 0 == false, любое другое число == true document.getElementById('btnRun').disabled = false; } Show(); } //обрабатываем нажатие кнопки "взять карту" function nextCard() { var oTest = document.getElementById('player'); var oSum = document.getElementById('sum'); //берем карту и показываем ее в окне браузера oTest.appendChild(player.nextCard().img); var s = player.calc(); //подсчитываем очки oSum.innerHTML = s; //показываем очки //делаем доступной карту "Крупье" document.getElementById('btnFinish').disabled = false; if (s > 21 && player.cards.length > 2) { //у игрока перебор. нет смысла продолжать document.getElementById('result').innerHTML = 'Не повезло'; player.currentBet = 0; document.getElementById('btnFinish').disabled = true; document.getElementById('btnRun').disabled = true; } Show(); } //обрабатываем нажатие кнопки "крупье" function finish() { document.getElementById('btnRun').disabled = true; document.getElementById('btnFinish').disabled = true; //находим элемент с id="dealer" var oDealer = document.getElementById('dealer'); //таково внутреннее правило казино - рисковать до 16 очков
while (dealer.calc() < 17) { //добавляем карты крупье и отображаем их oDealer.appendChild(dealer.nextCard().img); } switch (player.compare(dealer)) { case 1: document.getElementById('result').innerHTML = '!!! Победа !!!'; player.balance += player.currentBet * 2; player.currentBet = 0; break; case -1: document.getElementById('result').innerHTML = 'Не повезло'; player.currentBet = 0; break; default: // 0 - ровно document.getElementById('result').innerHTML = '??? Ровно ???'; break; } Show(); } //вспомогательная функция function Show() { //находим элемент с id='balance' и показываем баланс игрока //у крупье баланс не ограничен document.getElementById('balance').innerHTML = player.balance; document.getElementById('bet').innerHTML = player.currentBet; } Этот код можно добавить в файл blackjack.js. Сохраните все файлы в одной папке. Откройте файл blackjack.htm в браузере.
Вопросы 1. Какое назначение имеет язык Javascript? 2. Каким образом сценарий Javascript вставляется в HTML-документ? 3. Как объявляется переменная? Какие имена недопустимы? 4. Какие типы данных имеются в Javascript? 5. Как создаётся массив? С чего начинается нумерация элементов массива? 6. Перечислите и охарактеризуйте управляющие структуры Javascript. 7. Какие существуют в Javascript варианты синтаксиса создания функций? 8. Как создать несколько однотипных пользовательских объектов? 9. Как добавить метод к типу объекта? 10. Как создаётся объект при отсутствии необходимости определения его типа?
13. Лабораторная работа: Обработка событий при помощи сценариев Javascript Цель. Изучение приемов динамического изменения страницы в ответ на действия пользователя. Содержание •
Часть 1. Создание разметки
o o o •
1. Создание таблицы знаков калькулятора. 2. Затем создайте таблицу цифр: 3. Создание внешней таблицы.
Часть 2. Создание обработчиков событий
o o o o
1. Обработка цифр и знаков. 2. Обработка клавиши "=". 3. Самостоятельно напишите обработчик кнопки Очистить (C). 4. Последний штрих:
В данной работе предлагается создать HTML-таблицу, представляющую калькулятор, и создать ряд обработчиков событий - нажатий пользователя на кнопки, которые управляют логикой работы калькулятора.
Часть 1. Создание разметки 1. Создание таблицы знаков калькулятора. То, как предлагается оформить калькулятор в данной работе, показано на рис. 13.1
Рис. 13.1. Законченный вид таблицы-калькулятора Очевидно, таблица - наиболее подходящий элемент для представления набора элементов управления в виде выровненной сетки. Регулярность таблицы нарушается в нескольких местах: ячейка для результата шире всех остальных; клавиши операций отделены от цифр; нуль занимает две смежных ячейки. С точки зрения поведения также имеются отдельные смысловые группы: клавиши цифр должны обрабатываться одним образом; кнопки сброса и знак равенства - другим; ячейка результата клавишей не является. Поэтому сгруппируем элементы визуально и функционально в отдельные таблицы следующим образом. Сначала создайте в новом файле с именем Lab4.htm таблицу знаков следующего вида:
Ячейкам таблицы (элементу td) назначено стилевое правило, устанавливающее серый фон, выравнивание текста по центру, ширину и курсор в виде указателя: cursor: pointer;
2. Затем создайте таблицу цифр:
Здесь нуль занимает две смежных ячейки, и необходимо использовать атрибут colspan
3. Создание внешней таблицы. Теперь создайте таблицу с двумя строками. Во второй строке создайте две ячейки - в первую переместите таблицу цифр, а во вторую - таблицу знаков. В первой строке
нужна всего одна ячейка - для результата - на всю ширину строки. Воспользуйтесь еще раз атрибутом colspan. Ячейке результата назначьте атрибут id="result" и создайте для нее стиль (используя селектор идентификатора), назначив подходящий цвет фона, высоту и выравнивание текста по правому краю. Внешней таблице добавьте тонкую границу серого цвета и заголовок (элемент caption)
Часть 2. Создание обработчиков событий 1. Обработка цифр и знаков. Назначьте таблицам цифр и знаков атрибут id со значениями digits и signs соответственно. Ячейке с кнопкой сброса назначьте id='clear', а ячейке с кнопкой '=' - id='calculate'. Вставьте в раздел head документа элемент script, определяющий следующую функцию. //функция, выполняемая автоматически по окончании загрузки страницы window.onload = function() { //переменные, определенные здесь, доступны и во вложенных функциях var oDigits = document.getElementById('digits'); var oSigns = document.getElementById('signs'); var oResult = document.getElementById('result'); var oClear = document.getElementById('clear'); var oCalc = document.getElementById('calculate'); //Обрабатываем щелчок мыши по цифрам и знакам oDigits.onclick = oSigns.onclick = function(e) {//Mozilla FireFox и ряд других браузеров отправляет обработчик событий объект-событие //Internet Explorer не отправляет ничего var elem = null; //элемент, на котором произошло событие if (e) elem = e.target; //работает в FireFox else elem = window.event.srcElement; //работает в Internet Explorer if (elem && elem.tagName.toLowerCase() == 'td') { oResult.innerHTML += elem.innerHTML; } } }
в
Принципиально весь приведенный код делает две вещи: определяет действия, которые нужно проделать сразу по завершению загрузки документа браузером (т.е. при наступлении события window.onload), а также определяет действия, которые нужно выполнять в ответ на щелчок мышью по таблицам цифр и знаков (т.е. по событию onclick, возникающему в этих элементах). Действия представляют собой блоки кода, помещенные в функцию. Каждый оператор в блоке кода имеет свой смысл - в коде он пояснен комментариями, которые следует внимательно изучить. Проверьте работу скрипта: при щелчке мышью по обрабатываемым символам они должны добавляться к строке результата.
2. Обработка клавиши "=". Следом за функцией-обработчиком цифр и знаков (но внутри обработчика onload) добавьте следующую функцию.
//кнопке Равно (=) требуется специальная обработка oCalc.onclick = function(e) { if (!e) e = window.event; e.cancelBubble = true; //запрещаем передачу события родительскому элементу try { //перехватываем возможное исключение oResult.innerHTML = eval(oResult.innerHTML); //выполняем расчет выражения, записанного в строке } catch (ex) { } } Здесь идея заключается в том, что в ячейке result должно находиться арифметическое выражение. Чтобы вычислить его результат, нужно провести разбор выражения и пройти по дереву вычислений, что обычно реализуется относительно громоздким кодом. Но Javascript предоставляет один особенный метод - eval, который выполняет любой код Javascript, в том числе и арифметическое выражение! На случай, если выражение введено неправильно (не соответствуют скобки и т.п.), вызов метода eval следует заключить в блок try/catch - "попытайся"/"перехвати". Если исключительная ситуация возникнет, она будет перехвачена блоком catch, который не делает ничего (главное в том, что исключение считается в таком случае обработанным, и браузер не будет показывать сообщения об ошибке). Можно было бы, например, в этом блоке очистить поле result. Еще один важный момент: обработчик onclick назначен как ячейке calculate, так и содержащей ее таблице signs. Если специально не предотвратить передачу события родительскому элементу, то оно будет обработано дважды - сначала ячейкой, затем таблицей. Посмотрите, как бы это выглядело.
3. Самостоятельно напишите обработчик кнопки Очистить (C). 4. Последний штрих: Cделайте, чтобы обрабатывались еще два события - onmousedown и onmousedown "нажатие" и "отжатие" левой клавиши мыши. Пусть при нажатии цифра (или знак) изменяют цвет, а при отжатии возвращают первоначальный. Необходимые для этого команды приведены ниже, а обработчики, в которых они будут запускаться, напишите самостоятельно. elem.style.color = 'red'; elem.style.color = ''; Дополнительное задание. Добавьте к таблице кнопку sin. Если нажата эта кнопка, выражение должно меняться на Math.sin(выражение).
14. Лекция: Динамический HTML и Объектная Модель Документа Содержание • •
Программный доступ к элементам Объект window
o o o o o o •
Объект location Объект history Объект screen Коллекция frames Некоторые методы объекта window
Объект document
o o o o o o o o o •
Объект navigator
Объект body Коллекция all Коллекция anchors Массив images Коллекция forms Свойство cookie Поиск элемента по id Поиск групп элементов Программное создание, удаление и модификация HTML-элементов
Вопросы
Динамический HTML (DHTML) это целый ряд инновационных приемов, позволяющих динамически изменять оформление и содержание веб-страницы в ответ на действия пользователя. Динамические эффекты DHTML достигаются модификацией находящегося в памяти пользовательского компьютера HTML-документа без использования серверных технологий или сложных элементов управления. Поскольку не требуется перезагрузка документа с веб-сервера, все эти действия производятся быстрее и экономят сетевой трафик. DHTML не является технологией самой по себе, это продукт взаимодействия трех родственных и взаимодополняющих технологий: языка HTML, каскадных таблиц стилей (CSS) и языка сценариев (JavaScript или VBScript). Для предоставления сценариям доступа к HTML и CSS содержимое документа представляется в виде дерева объектов в программной модели, известной под названием Объектная Модель Документа (Document Object Model, DOM). Динамические стили – одно из ключевых преимуществ DHTML, и DOM модель предоставляет программный доступ к стилям, позволяя изменять стили элементов и создавать новые стилевые правила. Программный интерфейс (API) DOM модели является фундаментом DHTML, именно через DOM API программист может управлять практически любым элементом HTMLдокумента. Каждый элемент документа, видимый или невидимый, представляет собой отдельный объект, обладающий свойствами, связанными с атрибутами элемента, и методами, выполняющими некоторые действия. DOM модель позволяет также отслеживать действия пользователя, такие как движения и щелчки мыши или нажатия на клавиши. Любое такое действие генерирует событие, которое может быть перехвачено и передано функции-обработчику.
Программный доступ к элементам HTML-тэг элемента определяет тип сопоставленного ему объекта. Отдельные экземпляры объектов в документе могут идентифицироваться по их уникальному
идентификатору (атрибуту/свойству id), имени (атрибуту/свойству name) или положению в дереве элементов DOM модели. Кроме этого есть ряд важнейших объектов, которые не имеют собственных тэгов. Это такие объекты как window (окно браузера), document (HTML-документ, загруженный в окно или фрейм), event(событие).
Объект window Объект window является вершиной иерархии. Все остальные объекты являются дочерними или более отдаленными потомками объекта window. Браузер создает, как правило, единственный объект window, когда открывает документ в окне, однако если документ содержит фреймы (элементы frame и iframe), то дочерние объектыwindow создаются также для каждого фрейма. Доступ к дочерним окнам возможен через коллекцию frames родительского окна. Дочерние окна зависимы от состояния родительского окна. Например, закрытие родительского окна приводит к закрытию всех дочерних окон. Нет необходимости указывать объект window для вызова его свойств или методов, если вызов относится к текущему окну. Например, инструкции window.close() и close() идентичны. Многие свойства объекта window сами являются объектами. Рассмотрим важнейшие из них.
Объект navigator Объект navigator содержит информацию о браузере. Все его свойства доступны только по чтению и могут использоваться для программного определения свойств и методов, доступных в том или ином браузере. •
• • • • • • • • • • • • • • • • • • •
userAgent содержит строку, которая передается в HTTP заголовке на веб-сервер с каждым запросом. Эта строка содержит информацию о самом браузере и его версии, операционной системе и ее версии и некоторую дополнительную информацию. Пример: document.write(navigator.userAgent); /* Результат в Internet Explorer 8.0 Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6.4; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; OfficeLiveConnector.1.3; OfficeLivePatch.0.0) */ /* Результат в Mozilla Firefox 3.6 Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729) */ /* Результат в Apple Safari Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9.1 */ appName содержит имя браузера – "Microsoft Internet Explorer" или "Netscape" для многих других браузеров. appCodeName – "Mozilla" для большинства браузеров
appVersion, appMinorVersion, platform, systemLanguage и другие содержат информацию о версии браузера и операционной системы, языковые настройки и другое.
Объект location Объект location содержит полную информацию об адресе (Universal Resource Locator, URL) открытой страницы. Доступны также все отдельные детали URL, такие как протокол передачи данных, имя сервера, порт, через который осуществляется доступ, путь к файлу на сервере, строка запроса и закладка внутри страницы. Рассмотрим для примера следующий адрес: http://www.MyServer.ru:80/examples/samplecodes.aspx?code=html&level=1#l ocation. •
• • • • • • •
href содержит всю строку URL (http://www.MyServer.ru:80/examples/samplecodes.aspx?code=html&level=1#l ocation) protocol – протокол передачи данных (http:) host – имя сервера + порт (www.MyServer.ru:80) hostname – имя сервера (www.MyServer.ru) port – порт (80) pathname – путь (/examples/samplecodes.aspx) search – строка запроса (?code=html&level=1) hash – закладка, ссылка внутри страницы (#location)
Свойство href является идентичны.
свойством
по
умолчанию.
Две
следующие
инструкции
location = 'http://www.microsoft.com'; window.location.href = 'http://www.microsoft.com'; Присвоение значения объекту location (как в приведенном примере) немедленно открывает заданный URL в текущем окне.
Объект history Объект history (история) содержит информацию об адресах, посещенных пользователем с момента открытия браузера. Из соображений безопасности действительные адреса недоступны, имеются лишь три метода для перемещения по индексу на страницу относительно текущей. • • •
back() – переход на предыдущую страницу. Эквивалентно нажатию кнопки "Назад" в браузере. forward() – переход на следующую страницу. Эквивалентно нажатию кнопки "Вперед" в браузере. go(N) – переход на N позиций в индексе. history.go(1) эквивалентно history.back(), history.go(1) эквивалентно history.forward (). При попытке выйти за границы индекса не возникает ошибки; браузер остается на текущей странице.
Объект screen Объект screen содержит информацию о мониторе: ширина (width), высота (height), глубина цвета (colorDepth), выраженная как число бит на пиксель, и другие. Если у
пользователя несколько мониторов, отображаются данные того, в котором открыт браузер (или его большая часть).
Коллекция frames Коллекция frames содержит объекты, соответствующие Каждый такой объект содержит свой объект window.
элементам frame и iframe.
Некоторые методы объекта window Метод alert (предупреждение) открывает модальное окно сообщения с введенным в качестве аргумента текстом и единственной кнопкой. window.alert('Всем привет'); Метод confirm (подтверждение) открывает диалоговое окно с сообщением и кнопками "ОК" и "Отмена". Метод возвращаетtrue, если пользователь нажал "ОК" и false в противном случае. if (window.confirm('Хотите продолжить?') == true) RunMyScript(); Метод prompt (подсказка) открывает диалоговое окно с полем однострочного ввода и двумя кнопками. Метод возвращает введенную строку, если пользователь нажал "ОК" или null, если "Отмена". var name = window.prompt('Ваше имя:', 'не помню'); if (name != null) document.write("Добро пожаловать, " + name); else document.write("Добро пожаловать, неизвестный"); Метод setTimeout планирует выполнение определенной разработчиком функции через указанное время в миллисекундах и возвращает целочисленный идентификатор процесса, который может быть использован для отмены действия при помощи метода clearTimeout. function MyAction() { alert("Приступайте к действиям"); } var iTimer = window.setTimeout(MyAction, 10000); // обратите внимание на отсутствие скобок после MyAction // вариант: window.setTimeout("MyAction()", 10000); function StopAlert() { window.clearTimeout(iTimer); } В этом примере через 10 секунд (после открытия окна) будет запущена функция MyAction и выдано предупреждение, если только в результате каких-либо действий пользователя не будет вызвана функция StopAlert, отменяющая выполнение процесса. Метод setInterval выполняет указанное действие многократно через указанный промежуток времени в миллисекундах. Синтаксис метода аналогичен setTimeout. Повторы могут быть остановлены методом clearInterval.
<script type="text/javascript"> function MyClock() { var d = new Date(); //текущие дата и время компьютера пользователя document.getElementById('clock').innerHTML = d.toTimeString(); } var iClock = window.setInterval(MyClock, 1000); function StopClock() { window.clearInterval(iClock); } В этом примере функция MyClock выполняется каждую секунду. При выполнении функция получает системные дату и время локального компьютера (через объектDate) и отображает время в блоке с id="clock". Часы могут быть остановлены нажатием кнопки, которая вызывает функцию StopClock. Метод open открывает новое окно браузера и загружает в него документ из указанного адреса. var oNewWindow = window.open(sURL, sName, sFeatures, bReplace); Все аргументы метода необязательны. • • •
•
sUPL – адрес (URL) загружаемого документа. Если опущен, то about:blank sName – имя окна, которое может использоваться в атрибуте target (цель) элементов form и гиперссылки. sFeatures – строка, в которой через запятую перечисляются пары свойство=значение открываемого окна o height – высота окна в пикселях. В Internet Explorer 8.0 не может быть меньше 150. o width - ширина окна в пикселях. В Internet Explorer 8.0 не может быть меньше 250. o left – отступ левого края окна от левого края экрана в пикселях. o top – отступ верхнего края окна от верхнего края экрана в пикселях. Internet Explorer 8.0 не позволяет задавать отрицательные значения отступов и значения, превышающие размер экрана (открываемое окно должно быть видимым на экране). o location (yes/no) – задает, показывать ли в окне строку адреса. o status (yes/no) – задает, показывать ли в окне строку состояния. В Internet Explorer начиная с версии 7.0 установки location и status не имеют эффекта. Из соображений безопасности строки адреса и состояния должны быть видны. o resizable (yes/no) – разрешает или запрещает изменение размеров окна пользователем. Запрет допускается не во всех браузерах. o scrollbars (yes/no) – разрешает или запрещает полосы прокрутки, когда размер содержимого превышает размер окна. Если свойство опущено или задано no, полосы прокрутки отсутствуют. o menubar (yes/no), toolbar (yes/no) – разрешает или запрещает отображение строки меню и инструментов. Если опущены, то запрещены. bReplace (true/false) – определяет, добавлять адрес в историю браузера (false) или замещать текущий документ (true). Действует, только если документ
открывается в текущем значение _self, _parent или _top).
окне
(параметр sName имеет
Возвращаемое значение (oNewWindow) является ссылкой на (объект window) и открывает доступ к его свойствам и методам.
открываемое
окно
Окно, открытое методом window.open имеет свойство opener, являющееся ссылкой на объект window, в контексте которого был выполнен метод open. Метод close закрывает окно. Если окно не было открыто методом open, то выдается предупреждение о том, что сценарий пытается закрыть текущее окно.
Объект document Объект window содержит единственный объект document – HTML-документ. По разнообразию свойств и методов объект document не уступает объекту window. Именно через объект document осуществляется доступ к содержимому HTML-документа. Вот некоторые свойства и методы объекта document.
Объект body Объект body представляет собой HTML-элемент body. Это специальный случай, поскольку элемент body в документе единственный. Для обращения к остальным элементам документа могут использоваться стандартные методы объекта document.
Коллекция all Коллекция all поддерживается только Internet Explorer и содержит все элементы HTMLдокумента.
Коллекция anchors Коллекция anchors содержит все гиперссылки (объекты a), которые имеют атрибуты name или id. Эта коллекция полезна при создании списка гиперссылок.
Массив images Массив document.images содержит все изображения (элементы img), загруженные вместе с документом. Каждое изображение загружается на страницу отдельным файлом, и в случае динамической замены одного изображения другим может потребоваться время для загрузки нового файла. Чтобы избежать этого, можно заранее загрузить изображения, которые будут храниться в кэше браузера, откуда они доступны немедленно. ... ... <script type="text/javascript"> function ImagePreload() { var img = new Image(); img.src = 'myImg_over.jpg'; } window.onload = ImagePreload;
Коллекция forms Коллекция forms содержит все HTML-формы, определенные в документе. Доступ к каждому из объектов form возможен по индексу или по имени (если элементform имеет атрибут name, не являющийся стандартным).
Свойство cookie Cookie (буквально, печенье) – это небольшие фрагменты информации, хранимые браузером. Каждая cookie представляет собой пару имя=значение. Cookie может хранить до 20 таких пар. Cookie являются механизмом хранения пользовательских настроек и поддержания диалога между веб-сервером и браузером. веб-сервер может отправлять браузеру инструкцию SetCookie с парами имя=значение, и браузер возвращает эту же пару серверу (только тому, который установил cookie) при каждом запросе, что позволяет серверу установить, с кем (чем) ведется диалог. Cookie имеют время жизни. Если параметр expires (истечение срока) не задан или установлен на дату в прошлом, то cookie не сохраняются на диске локального компьютера и уничтожаются при закрытии браузера. Если параметрexpires установлен на дату в будущем, то cookie сохраняются на диске в виде текстового файла и автоматически удаляются по истечении срока годности. Cookie могут также читаться и создаваться в браузере при помощи языков сценариев. Свойство document.cookie представляет собой строку, содержащую пары имя=значение, разделенные точкой с запятой и пробелом ("; "). Таким образом, для получения отдельных значений требуется разбор строки. <script> // Создает куки с определенными именем и значением. // срок действия установлен до конца XXI века. function SetCookie(sName, sValue) { document.cookie = sName + "=" + escape(sValue) + "; expires=Fri, 31 Dec 2099 23:59:59 GMT;"; } // Возвращает значение куки по его имени. function GetCookie(sName) { // пары разделены "; " // метод split расщепляет строку на массив строк var aCookie = document.cookie.split("; "); for (var i = 0; i < aCookie.length; i++) { // теперь следует расщепить каждую пару имя=значение var aCrumb = aCookie[i].split("="); if (sName == aCrumb[0]) return unescape(aCrumb[1]); } // Куки с запрошенным именем не существует return null; } // Удаляет куки с заданным именем. function DelCookie(sName) { document.cookie = sName + "=; expires=Fri, 21 Dec 1976 04:31:24 GMT;"; }
Поиск элемента по id Элемент может быть найден в документе по его id. Поиск по id
Transitional//EN"
<script type="text/javascript"> function ShowDetails() { var elem = document.getElementById('details'); elem.style.display = 'block'; }
Нажмите кнопку для просмотра подробностей
Здесь описаны все подробности.
В этом примере метод объекта document (HTML-документ) getElementById ищет элемент, атрибут id которого равен указанному (в данном примере "details"); строчные и заглавные буквы в значении атрибута различаются. Internet Explorer предлагает более простой доступ к элементу по его id. Достаточно просто указать id элемента. function ShowDetails() { details.style.display = 'block'; } Следует иметь в виду, что такой подход не является стандартным и не гарантирует обнаружение элемента в других браузерах. Использование DOM методаgetElementById гарантирует работу в большинстве браузеров. Предполагается, что id задает уникальный в пределах документа идентификатор элемента.
Поиск групп элементов DOM-метод getElementsByTagName ищет элементы по имени HTML-тэга в пределах элемента, в контексте которого выполняется метод. // коллекция таблиц в документе var oTables = document.body.getElementsByTagName('table'); document.write("В документе " + oTables.length + " таблиц"); // коллекция ячеек первой таблицы var oCells = oTables[0].getElementsByTagName('td');
DOM-метод getElementsByName ищет элементы в документе по значению атрибута name (атрибут name поддерживают управляющие элементы HTML-формы). ... //все элементы переключателя var oAge = document.getElementsByName('Age'); // текстовое поле UserName var oUserName = document.getElementsByName('UserName')[0]; // даже если найден единственный объект, // он является элементом массива // Тот же результат во всех браузерах: var oForm = document.forms[0]; var oAge = oForm.Age; // массив элементов var oUserName = oForm.UserName; //единственный элемент Замечание: Методы getElementById, getElementsByName и getElementsByTagName дост упны только после полной загрузки документа. Например, следующий код не работает. <script type="text/javascript"> document.getElementById('MyDiv').innerHTML = "Hello";
Программное создание, удаление и модификация HTMLэлементов DOM модель представляет HTML-документ в виде дерева, в узлах которого находятся HTML-элементы. Каждый узел дерева (кроме корневого) имеет единственный родительский узел (parentNode) и может иметь дочерние (childNodes) и "братские" (siblings) узлы, т.е. узлы, имеющие общего родителя. Модификация документа DOMметодами заключается в создании нового элемента и размещения его в определенном узле, удалении или изменении узла. Следующий пример показывает создание списка опций в форме в ответ на выбор пользователя с использованием DOM-методов createElement (создать HTMLэлемент), appendChild (добавить элемент к родительскому элементу в качестве дочернего) и removeChild (удалить дочерний элемент). Песенка-загадка
<script type="text/javascript"> function CreateList(listType) { var maleOptions = ["веснушки", "хлопушки", "линейки", "батарейки"]; var femaleOptions = ["цветочки", "звоночки", "тетрадки", "переглядки"]; //ищем элемент(ы) по имени var oSelect = document.getElementsByName('Interest'); if (oSelect && oSelect[0]) //если элемент найден, удаляем его из родительского узла oSelect[0].parentNode.removeChild(oSelect[0]); // создаем элемент select (список опций) oSelect = document.createElement('select'); oSelect.name = 'Interest'; oSelect.multiple = true; //разрешаем множественный выбор var opArray = null; // выбираем массив опций в зависимости от выбора пользователя if (listType == 'm') opArray = maleOptions; else opArray = femaleOptions; for (var i = 0, n = opArray.length; i < n; i++) { //создаем элемент var op = document.createElement('option') op.innerHTML = opArray[i]; //добавляем в новый элемент в конец списка oSelect.appendChild(op); } //список еще не виден. добавляем его в родительский узел document.getElementById('divList').appendChild(oSelect); } В этом же примере использовано свойство innerHTML, не являющееся частью DOMмодели, но поддерживаемое большинством браузеров. Это свойство содержит весь HTML-код (включая текст и разметку) между открывающим и закрывающим тэгами элемента (но не сами тэги). Использование innerHTML существенно упрощает процесс программирования и поэтому весьма популярно.
Вопросы 1. Для чего используется динамический HTML? Какие технологии он сочетает?
2. Что такое Объектная Модель Документа и какую роль играет она в динамическом HTML? 3. Кратко охарактеризуйте объекты window, history, navigator, document, location, screen. 4. Перечислите и охарактеризуйте наиболее часто употребляемые методы объекта window. 5. Что такое cookie? Как создавать и читать cookies? 6. С помощью какого метода можно найти в документе элемент по его id? 7. С помощью какого метода можно найти в документе все элементы определённого типа? 8. Какие методы DOM используются для создания и удаления элементов? 9. Что даёт свойство innerHTML?
15. Лабораторная работа: Динамический HTML Цель. Изучение приёмов динамического формирования HTML-документа. Содержание •
Часть 1. Создание разметки
o o •
1. Создание выпадающего списка (элемент select). 2. Создание остальной разметки
Часть 2. Создание сценария, манипулирующего таблицей
o o o o o o
1. Добавление пунктов заказа 2. Отладка сценария. 3. Функция Calculate. 4. Функция RemoveProduct(elem). 5. Функция RemoveSelected. 6. Функция ToggleCheck.
В данной работе будет создана страница формирования клиентом заказа из набора продуктов. При выборе клиентом продукта, указании количества единиц и нажатии кнопки "Добавить в корзину" к таблице заказа добавляется пункт. Кнопка "Удалить" позволяет удалять пункты из заказа по одному или группой. При всех манипуляциях подсчитывается число единиц заказанных товаров и их суммарная стоимость.
Часть 1. Создание разметки Статическая часть страницы будет иметь следующий вид (рис. 15.1).
Рис. 15.1. Начальный вид формы заказа при открытии страницы Рассмотрим действия по созданию этой формы пошагово.
1. Создание выпадающего списка (элемент select). В теле нового документа с именем Lab5.htm создайте элемент div, в котором будет размещена вся разметка данного примера. Первый элемент - select - должен содержать несколько групп (optgroup) по несколько пунктов (option). Каждый пункт содержит наименование какого-либо продукта, а его атрибут value - цену (произвольное в данном случае число). В развёрнутом виде список должен выглядеть так:
2. Создание остальной разметки Следом за выпадающим списком создайте два элемента ввода - input type="text" и input type="button" (примеры приведены в лекции). Текстовому элементу ввода назначьте атрибут id="txtQty", а кнопке - onclick="AddToCart()". Последний элемент разметки - таблица с заголовком (элемент caption), верхним и нижним колонтитулом (элементы thead и tfoot) и телом (элемент tbody). Описания и примеры применения этих элементов также см. в соответствующей лекции. Таблице назначьте атрибут id="tblOrder". Раздел tbody оставьте пустым (он будет формироваться динамически), а в колонтитулах, как видно на рисунке, следует расположить по одному элементу управления - checkbox и button. Им сразу задайте обработчики события click следующим образом:
Часть 2. таблицей
Создание
сценария,
манипулирующего
1. Добавление пунктов заказа Создайте скрипт в конце тела документа, и сразу определите обработчики, назначенные элементам управления в предыдущем задании - пока пусть это будут функции с пустым телом. В начало скрипта поместите следующие команды: var tbl = document.getElementById('tblOrder');
var oList = document.getElementById('lstProducts'); Ссылки на элементы 'tblOrder' (таблица заказа) и lstProducts (список выбора продукта) будут часто использоваться в коде сценария, поэтому целесообразно определить их единожды. При нажатии кнопки "Добавить в корзину" в таблицу должны добавляться строки, соответствующие пунктам заказа:
Функция-обработчик этой кнопки была названа AddToCart. Изучите её код и добавьте его в скрипт. /* Добавление пунктов заказа */ function AddToCart() { /* Определяем значение, введённое в текстовое поле */ var qty = document.getElementById('txtQty').value; /* Проверка: распознаётся ли значение как число? Если нет, считаем единицей */ if (parseFloat(qty) != qty) qty = 1; /* Вставляем строку в тело таблицы */ var oRow = tbl.tBodies[0].insertRow(-1); /* В добавленную строку вставляем, во-первых, checkbox */ oRow.insertCell(-1).innerHTML = ''; /* во-вторых, текст, взятый из списка выбора продуктов */ oRow.insertCell(-1).innerHTML = oList.options[oList.selectedIndex].text; /* в-третьих, цена выбранного продукта */ oRow.insertCell(-1).innerHTML = oList.value; /* далее, количество, указанное в текстовом поле */ ... /* затем стоимость пункта заказа */ ... /* и, наконец, кнопку "Удалить" */ ... /* По окончании вставки строки необходимо пересчитать сумму заказа */ //Calculate(); } Код в тех строках, где оставлено многоточие, напишите самостоятельно, опираясь на комментарии. Вызов функции Calculate() оставьте пока закомментированным - эту функцию мы добавим позже, а сначала следует добиться верной работы AddToCart().
Лучший способ проследить ход работы сценария - это выполнить его пошагово в отладчике. IE8 предлагает встроенный отладчик в наборе средств разработчика (Меню Сервис - Средства разработчика). Для некоторых других браузеров также существуют отладчики, доступные как плагины - например, FireBug. Откройте страницу в IE8 и запустите Средства разработчика. На вкладке Сценарий имеются кнопки для запуска отладки и пошагового выполнения команд сценария. На правой панели можно просмотреть локальные переменные (определённые в текущей функции), а также произвольные выражения, включающие объекты модели документа, их свойства и даже вызовы методов. Поставьте точку останова на начало интересующей нас функции и запустите отладку. Нажав кнопку "Добавить в корзину" на веб-странице, вы тем самым запустите обработчик события click, и отладчик покажет команду в точке останова. Двигайтесь пошагово, наблюдая за всеми объектами, влияющими на логику обработчика. Отладка помогает выявить те ошибки в программе, которые появляются вследствие неточного понимания смысла тех или иных свойств и методов объектов модели документа - всегда можно посмотреть, чему в действительности равно то или иное свойство, или что выдаёт тот или иной метод. Также можно выявить ошибки, связанные с логикой программы - запускается ли функция при наступлении события, верно ли сформулированы условный и циклический операторы и, наконец, если возникает исключение, то на какой команде и в каком контексте. Но те ошибки, которые связаны с синтаксисом, отладчик вряд ли поможет найти - во многих случаях браузер просто не поймёт сценария с такими ошибками. Особенно тщательно следует следить за соответствием скобок и тэгов, а также символами-разделителями.
3. Функция Calculate. Создайте функцию Calculate() и функции AddToCart.
уберите
комментарий
с
её
вызова
в
function Calculate() { /* Счётчики для количества единиц товара и общей стоимости */ var qty = 0, amount = 0; /* Цикл по всем строкам в теле таблицы */ for (var i = 0, n = tbl.tBodies[0].rows.length; i < n; i++) { /* Увеличиваем qty на значение в 3 столбце текущей строки */ qty += parseFloat(tbl.tBodies[0].rows[i].cells[3].innerHTML); /* Увеличиваем amount на значение в 4 столбце текущей строки */ amount += parseFloat(tbl.tBodies[0].rows[i].cells[4].innerHTML); } /* Записываем qty в 3 столбец нижнего колонтитула */ ... /* Записываем amount в 4 столбец нижнего колонтитула */ ... } Код в тех строках, где оставлено многоточие, напишите самостоятельно, опираясь на комментарии.
4. Функция RemoveProduct(elem). Кнопка "Удалить", динамически вставляемая в правую ячейку каждой строки заказа, должна выполнять свою работу - следовательно, необходимо назначить ей обработчик (назовём его RemoveProduct) и написать его код. Этот обработчик имеет существенное отличие от предыдущих, которое заключается в том, что смысл его работы зависит от контекста вызова: удалять нужно именно ту строку, в которой кнопка расположена.
Таким образом, обработчик должен принимать параметр, определяющий контекст. Это можно сделать различными путями, и здесь мы предлагаем наиболее типичный. Если назначить кнопке обработчик следующим образом: onclick="RemoveProduct(this)", то функция RemoveProduct получит в качестве параметра ссылку на тот объект, который принял событие (в данном случае - щелчок мыши). Очевидно, обладая ссылкой на элемент в таблице, можно каким-то образом определить номер (index) строки таблицы, в которой он находится, и применить метод таблицы deleteRow(index). Отношение между строкой и кнопкой "Удалить" такое: строка является контейнером ячейки, которая является контейнером кнопки. Ссылку на контейнер элемента можно получить при помощи свойства parentNode этого элемента. С учётом этих соображений код рассматриваемой функции примет следующий вид: function RemoveProduct(elem) { tbl.deleteRow(elem.parentNode.parentNode.rowIndex); Calculate(); } Вставьте эту функцию в скрипт (и не забудьте правильно описать её вызов в динамическом определении кнопки - см. функцию AddToCart). Сохраните документ, обновите страницу в браузере и проверьте добавленную функциональность.
5. Функция RemoveSelected. Код этой функции представлен ниже, и на нём следует остановиться подробнее, поскольку работа по удалению элементов из множества имеет свои тонкости. function RemoveSelected() { /* находим все элементы input в теле таблицы */ var checks = tbl.tBodies[0].getElementsByTagName('input'); var i = 0; /* начинаем перебор элементов в цикле */ while (i < checks.length) { /* рассматриваем элемент лишь в том случае, если это checkbox и он отмечен */ if (checks[i].type == 'checkbox' && checks[i].checked) /* вызываем функцию, которая удалит строку с пунктом заказа - передаём ей ссылку на checkbox */ RemoveProduct(checks[i]); else /* счётчик увеличиваем лишь в том случае, если удаление не было сделано */ i++; } } Множество ссылок на все элементы ввода (input) внутри тела таблицы (tbody) легко получить при помощи метода getElementsByTagName. Этот метод принимает в качестве параметра имя тэга и выдаёт массив ссылок. Важно отметить, что ссылками являются не только элементы массива, но и сам массив - ссылочный, т.е. все изменения в документе автоматически отражаются в этом массиве. Таким образом, удалив строку из таблицы (и тем самым удалив из неё два элемента input- checkbox и button), мы тем самым уменьшим число элементов в массиве checks на 2. Это следует принимать во внимание при циклической обработке массива. Номер рассматриваемого в цикле элемента массива обозначен в данном примере переменной i, и отсчёт, как обычно, начинается с нуля. Чтобы правильно сформулировать оператор увеличения этого i, следует задаться вопросом: "Рассмотрев элемент с номером i, элемент с каким номером следует рассматривать далее?" Ответ таков: "Если удаление не было выполнено, то i+1; иначе - вновь i (теперь это номер
следующего из оставшихся элементов)". Поэтому цикл записан именно таким образом (а не с использованием оператора for).
6. Функция ToggleCheck. Последняя функция данного сценария создаёт дополнительное удобство: можно отметить или сбросить сразу все галочки в пунктах заказа, щёлкнув по галочке (элементу checkbox) в заголовке таблицы. Этому элементу назначена функцияобработчик ToggleCheck, принимающая в качестве параметра this, т.е. ссылку на объект-источник события. Напишите эту функцию самостоятельно - все необходимые для этого приёмы уже рассмотрены. Окончательный вид работающей страницы показан на рис. 15.2.
Рис. 15.2. Действующая страница заказа Дополнительное задание. Сделайте так, чтобы при добавлении продукта, который в заказе уже присутствует, новая строка не добавлялась, а вместо этого увеличивалось бы количество уже заказанных единиц этого продукта. Для этого вам потребуется создать объект, хранящий количества заказанных единиц продукта, в котором ключами будут названия продукта, а значениями - количества. Понадобится, естественно, модифицировать все функции, изменяющие содержание заказа - так, чтобы в объекте эти изменения также отражались.
16. Лекция: События. Объект event Содержание • • • • • •
Передача объекта event функции-обработчику Передача элемента-источника функции-обработчику Связывание элемента-источника и события с функцией-обработчиком Пример: Фотогалерея Об использовании ключевого слова this Вопросы
Обработка событий занимает центральное место в разработке динамических вебстраниц. С точки зрения DOM API, событие – это сообщение, отправляемое в ответ на некоторое действие, например, завершение загрузки документа, перемещение или щелчок мыши, нажатие клавиши. Событие может быть принято (перехвачено) и обработано программными средствами. Обработчик события – это, как правило, функция, написанная на языке сценариев (например, JavaScript), которая выполняет действия, когда произошло соответствующее событие. Вот список основных событий: •
•
•
•
События окна и документа: onload – документ загружен и противоположное событие onunload – документ выгружен из окна. Применяется к элементам body иframeset и объекту window. События мыши: onclick – (одиночный) щелчок мыши и ondblclick – двойной щелчок. Одиночный щелчок может быть разложен на два события, onmousedown – кнопка мыши нажата и onmouseup – кнопка мыши отпущена. Отслеживаются также перемещения мыши: onmouseover – указатель мыши пересек границу объекта внутрь, onmouseout - указатель мыши пересек границу объекта наружу и onmousemove – мышь перемещается над объектом. Применяется к большинству элементов. События клавиатуры: onkeypressed – нажата и отпущена клавиша, производящая символ. Это событие разделяется на два, onkeydown – клавиша нажата и onkeyup –клавиша отпущена. Применяется к большинству элементов. События HTML-формы onsubmit и onreset и элементов формы onfocus, onblur и onchange рассмотрены в лекции "HTML формы".
Объект window.event создается браузером автоматически в момент возникновения события и доступен только внутри функции-обработчике события. Следует подчеркнуть, что модель объекта event в Internet Explorer существенно отличается от используемой в других браузерах, и требуется большое внимание при разработке динамических страниц, предназначенных для разных браузеров. Тем не менее, целый ряд свойств оказывается одинаковым во всех современных браузерах. • •
• •
type – тип события без приставки "on". Например, событие onclick имеет тип click. button – нажатая кнопка мыши (0 – ни одна, 1 – левая, 2 – правая, 3 – левая и правая, 4 – средняя, 5 – левая и средняя, 6 – правая и средняя, 7 – все три). Это свойство имеет смысл для событий мыши. В случае остальных событий имеет значение 0 независимо от действительного состояния кнопок. clientX, clientY – координаты указателя мыши относительно верхнего левого угла клиентской области окна браузера. screenX, screenY - координаты указателя мыши относительно верхнего левого угла дисплея.
keyCode – целочисленный код клавиши, которая вызвала событие клавиатуры. Коды клавиш различаются для различных аппаратных платформ (PC или Macintosh). shiftKey, ctrlKey, altKey – истина (true), если во время события нажата также клавиша Shift, Ctrl или Alt, соответственно. cancelBubble – запрещает (true) или разрешает (false, по умолчанию) передачу события вверх по иерархии от элемента-источника к родительскому элементу. Каждое событие происходит на единственном элементе-источнике. Если элементу-источнику не сопоставлена функция-обработчик, событие передается вверх по дереву элементов, пока не встретит функцию-обработчик или не достигнет корневого элемента. Если функция-обработчик найдена, но не содержит cancelBubble=true, то передача вверх продолжается, если содержит, то прерывается.
На этом список общих свойств заканчивается. Большинство остальных свойств объекта event доступны в различных браузерах под разными именами. • •
Элемент-источник события в Internet Explorer доступен как свойство srcElement, в Mozilla Firefox и других как target. События onmouseover и onmouseout в Internet Explorer показывают свойстваобъекты откуда (fromElement) и куда (toElement). В Mozilla Firefox эти объекты являются свойством relatedTarget.
Список различий можно продолжить. Несмотря на различия в объектной модели между браузерами, писать веб-страницы, работающие в разных браузерах, можно и нужно. Рассмотрим это на примерах.
Передача объекта event функции-обработчику Как было сказано, событие передается вверх по иерархии от элемента-источника к родительскому элементу и дальше. Процесс может быть остановлен присвоением свойству cancelBubble значения true. <script type="text/javascript"> function checkCancel() { if (window.event.shiftKey) window.event.cancelBubble = true; } function showSrc() { if (window.event.srcElement.tagName == "IMG") alert(window.event.srcElement.src); } ... ... В этом примере и элемент img, и его родительский элемент body имеют обработчик события onclick. При щелчке по изображению сначала вызывается функцияcheckCancel, которая проверяет состояние клавиши Shift. Если клавиша нажата, передача вверх по иерархии прекращается, если нет, выполняется также функция showSrc. К сожалению, этот пример работает только в Internet Explorer (начиная с версии 4.0). Различия в объектной модели Internet Explorer и большинства других браузеров максимальны именно в объекте event и доступе к нему. В случае Internet Explorer объект event доступен в функции-обработчике как глобальный
объект, в других браузерах этот объект создается элементом-источником и доступен при вызове обработчика. Перепишем код следующим образом: <script type="text/javascript"> function checkCancel(e) { if (e.shiftKey) e.cancelBubble = true; } function showSrc(e) { if (e.srcElement.tagName == "IMG") alert(e.srcElement.src); } ... ... В этом варианте функция checkCancel работает как в Internet Explorer, так и в Mozilla Firefox, Apple Safari и Google Chrome, однако функция showSrc по-прежнему работает только в Internet Explorer. Дело в том, что элемент-источник события доступен в Internet Explorer как свойство события srcElement, а в других браузерах как target. Для учета различий можно применить один из нескольких методов: 1. Написать отдельные страницы для каждого браузера. Его мы обсуждать не будем. 2. Определить используемый браузер (при помощи объекта window.navigator). 3. function showSrc(e) { 4. // userAgent в Internet Explorer любой версии содержит 5. // подстроку 'MSIE', которой нет в других браузерах 6. var isIE = window.navigator.userAgent.indexOf('MSIE') > -1; 7. if (isIE) { 8. if (e.srcElement.tagName == "IMG") 9. alert(e.srcElement.src); 10. } 11. else { 12. if (e.target.tagName == "IMG") 13. alert(e.target.src); 14. } 15. } Такой подход использовался и используется, однако он имеет существенный недостаток: мы не знаем, существует ли свойство target у объекта event в "другом" браузере. 16. Определить наличие интересующего свойства. Этот подход считается более плодотворным. 17. function showSrc(e) { 18. var elem = null; 19. if (e.srcElement) 20. elem = e.srcElement; 21. else if (e.target) 22. elem = e.target; 23. 24. if (elem != null) { 25. if (elem.tagName == "IMG") 26. alert(elem.src); 27. } 28. else { 29. alert("Ваш браузер не поддерживает DOM модель");
Передача элемента-источника функции-обработчику Элемент (объект) может быть передан в сценарий как аргумент функции-обработчика. Динамический стиль JavaScript
Transitional//EN"
<script type="text/javascript"> function ChangeStyleOver(elem) { elem.style.color = 'red'; elem.style.fontSize = 'large'; } function ChangeStyleOut(elem) { elem.style.color = 'Black'; elem.style.fontSize = 'normal'; }
В этом примере стиль абзаца (элемент p) задан в самом элементе. При наведении мыши (событие onmouseover) вызывается функция ChangeStyleOver, в которую передается ссылка на объект-элемент (в этом контексте this указывает на элемент p). Функция изменяет цвет текста (атрибут стиля color / свойство объектаstyle color) и размер шрифта (font-size / fontSize). Обратите внимание на общее правило: все имена свойств начинаются со строчной буквы; если имя CSS атрибута содержит дефис (-), то дефис удаляется и следующая буква делается заглавной (стиль "спина верблюда"). Когда пользователь отводит мышь от элемента (событие onmouseout), функция ChangeStyleOut возвращает стиль элемента к исходному. Изменения вступают в силу немедленно. Замечание: Того же эффекта можно добиться без использования сценария. CSS псевдо-класс :hover применяется к элементу, над которым находится указатель мыши. Динамический стиль CSS <style type="text/css"> p { color: Black; font-size: normal; } p:hover { color: red; font-size: large; }
Элемент !DOCTYPE в данном примере обязателен, если просматривать страницу в Internet Explorer 7.0 или более новом. В предыдущих версиях пример не работает, поскольку псевдо-класс :hover поддерживается только элементом a (гиперссылкой).
Связывание элемента-источника и события с функциейобработчиком Для того, чтобы обработать событие, произошедшее на том или ином элементе, элемент-источник и событие должны быть связаны со сценарием обработки события (функцией-обработчиком). Сделать это можно различными способами. 1. Инструкция может помещаться в самом элементе. 2.
3. текст
Ключевое слово this в этом контексте является ссылкой на элемент-источник (объект p, абзац). Такой подход удобен, когда нужно добавить небольшие инструкции в немногих местах. 4. В элементе помещается вызов функции-обработчика. 5.
6. текст
Функция-обработчик может принимать аргументы, которые при вызове помещаются в круглые скобки. Специальными случаями является объектисточник (this) и событие (event), рассмотренные выше. Даже если список аргументов пуст, круглые скобки обязательны. 7. Обработчик события может быть помещен в специальный блок сценария (script) с указанием элемента и события. 8. <script type="text/javascript" for="oButton" event="onclick()"> 9. var sMessage1 = "Flip" 10. var sMessage2 = "Flop" 11. if (oButton.innerText == sMessage1) { 12. oButton.innerText = sMessage2; 13. } 14. else { 15. if (oButton.innerText == sMessage2) { 16. oButton.innerText = sMessage1; 17. } 18. } 19. 20. 21. В этом примере сценарий выполняется, когда произошло событие, определенное в атрибуте EVENT, на элементе, id которого задан в атрибуте FOR. Пример работает только в Internet Explorer.
22. Функция-обработчик может быть связана с объектом-источником и событием программно, если по какой-либо причине нежелательно помещать ее вызов в тэг элемента. Рассмотрим этот прием на примере.
Пример: Фотогалерея Начинающий разработчик хочет создать свою фотогалерею и размещает на странице маленькие изображения, являющиеся гиперссылками на изображения большего размера. Моя галерея
Сразу же обнаруживается, что каждая ссылка ведет на новую страницу, а разработчику хотелось бы, чтобы каждая большая фотография появлялась на этой же странице. Кроме того, он планирует время от времени менять фотографии, не меняя ничего больше. Более опытный разработчик предлагает ему решение: поместить на веб-сервер два файла, сценарий JavaScript и каскадную таблицу стилей и добавить в заголовок страницы (элемент head) единственную строчку <script type="text/javascript" src="Gallery.js"> Каскадная таблица стилей BigImg.css описывает стили двух элементов, контейнера с абсолютным позиционированием на странице и вложенного в него элементаdiv. #BigImgContainer { border:solid 1px #ccc; background:#fff; width:150px; height:150px; position:absolute; top:100px; left:200px; padding:8px; display:none; } #BigImgContainer div { color:Red; } Весь сценарий реализован в файле Gallery.js.
/* Все свойства и методы объект document доступны только после загрузки страницы поэтому помещаем код в обработчик window.onload */ window.onload = function() { // находим элемент, в котором должны располагаться // гиперссылки на изображения var oGallery = document.getElementById('gallery'); if (!oGallery) { // элемент не найден. сообщаем инструкции по использованию alert("Для правильной работы в документе должен быть элемент с id='gallery'\nПример:\n\
\n\ \n
"); return; //выход из функции. Дальнейшие инструкции не выполняются } // if //Галерея найдена. Можно продолжать. // загружаем таблицу стилей var oLink = document.createElement('link'); oLink.rel = 'stylesheet'; oLink.type = 'text/css'; oLink.href = 'BigImg.css'; //и добавляем ее в элемент head document.documentElement.firstChild.appendChild(oLink); // создаем рамку, в которую будет загружаться изображение var oDiv = document.createElement('div'); oDiv.id = 'BigImgContainer'; //создаем вспомогательный элемент, //отображаемый во время загрузки изображения var oLoading = document.createElement('div'); oLoading.innerHTML = 'Идет загрузка...'; // создаем объект изображение var oBigImg = new Image(); //добавляем созданные объекты в дерево документа oDiv.appendChild(oLoading); oDiv.appendChild(oBigImg); document.body.appendChild(oDiv); //находим все гиперссылки в блоке gallery var oAnchors = oGallery.getElementsByTagName('a'); for (var i = 0, n = oAnchors.length; i < n; i++) { //каждый элемент связываем с функцией-обработчиком oAnchors[i].onclick = function() { oDiv.style.width = ''; // вернуть к заданному по умолчанию oDiv.style.height = ''; oDiv.style.display = 'block'; oBigImg.style.display = 'none'; // Загрузка мжет занять время. Показываем сообщение oLoading.style.display = 'block'; //запускаем загрузку изображения oBigImg.src = this.href; // this == oAnchors[i] // Функция должна возвращать false, // чтобы предотвратить переход по ссылке return false; } //oAnchors[i].onclick } //for //функция будет выполняться каждый раз после загрузки нового изображения oBigImg.onload = function() { // мы не знаем размеров изображения, пока оно не загружено oDiv.style.width = this.width + 'px'; // this == oBigImg oDiv.style.height = this.height + 'px';
// скрываем рамку с изображением по щелчку мыши oDiv.onclick = function() { this.style.display = 'none'; // this == oDiv } //oDiv.onclick //window.onload
Сценарий содержит единственную анонимную функцию, которая вызывается автоматически после окончания загрузки HTML-документа. Внутри функции производит проверка наличия элемента, в котором должны располагаться ссылки, после чего создается контейнер для большой фотографии и объект Image, изначально не связанный с файлом изображения. Далее сценарий находит все гиперссылки, расположенные в объекте oGallery (
), и создает для каждой из них собственный обработчик события onclick. Гиперссылка имеет встроенное действие по щелчку мыши, но событие onclick происходит раньше, что позволяет предотвратить встроенное действие. Внутри обработчика происходит визуализация контейнера oDiv и инициализация загрузки большого изображения. Загрузка всегда происходит асинхронно, и функция-обработчик не дожидается ее окончания и возвращает false, чтобы предотвратить переход по гиперссылке. По окончании загрузки изображения срабатывает обработчик события oBigImg.onload. Только в этот момент сценарий может определить размер полученного изображения и скорректировать под него размеры контейнера. Наконец, обработчик oDiv.onclick позволяет убрать контейнер с изображением с экрана. Сценарий работает в любом браузере, поддерживающем JavaScript.
Об использовании ключевого слова this Ключевое слово this является ссылкой на объект, в контексте которого выполняется обращение к свойству или методу. В большинстве случаев thisиспользуется в конструкторах объектов и в функциях-обработчиках событий. //Пример function this.x this.y }
1 MyFoo(x, y) { = x; = y;
//Корректный вызов. var obj1 = new MyFoo(1, 2); /* MyFoo является конструктором объекта obj1, this является ссылкой на этот объект, который получает свойства x и y со значениями 1 и 2. */ // Некорректный вызов. var obj2 = MyFoo(1, 2); /* MyFoo вызвана как обычная функция. Такой вызов осуществляется в контексте объекта window. Объект window приобретает свойства x и y со значениями 1 и 2, переменная obj2 значение undefined (поскольку MyFoo не возвращает значения). */ //Пример 2 function SumSquares() { return this.x * this.x + this.y * this.y; }
// Добавляем функцию SumSquares к методам объектов MyFoo. MyFoo.prototype.SumSquares = SumSquares; // Обратите внимание на отсутствие круглых скобок. //Корректный вызов. var a = obj1.SumSquares(); // Здесь круглые скобки обязательны //Некорректный вызов. var b = SumSquares(); /* Функция вызвана в контексте объекта window, у предполагается) свойств x и y. */ //Чтобы избежать ошибок как в примере 2, //лучше задать метод SumSquares как анонимную функцию. MyFoo.prototype.SumSquares = function() { return this.x * this.x + this.y * this.y; }
которого
нет
(не
Вопросы 1. 2. 3. 4. 5. 6. 7. 8.
Что такое событие? Перечислите основные события. Перечислите свойства объекта event. Как получить доступ к объекту event в функции-обработчике события - в IE и других браузерах? Как получить доступ к элементу-источнику события, имея объект event? Как передать обработчику события ссылку на элемент-источник? Как происходит связывание элемента-источника и события с функциейобработчиком? Какой смысл имеет ключевое слово this в функциях-обработчиках событий?
input type="text" input type="password" input type="hidden" input type="checkbox" input type="radio" input type="file" input type="submit" input type="image" input type="reset" input type="button" Элемент button Элемент select Элемент textarea Вспомогательный элемент label
Программный доступ к форме и ее элементам Безопасность форм Вопросы
Современный интернет немыслим без взаимодействия с пользователем. Форумы, вебстраницы электронной почты, электронная коммерция, все это требует отправки тех или иных данных от пользователя на веб-сервер. Этой цели служат HTML-формы. HTML-форма – это часть HTML-документа, содержащая, помимо обычного содержимого и разметки, специальные элементы, называемые элементами управления (поля ввода, флажки, переключатели, списки и т.д.). Пользователь заполняет форму, то есть изменяет элементы управления, перед отправкой формы на обработку (например, на веб-сервер или в почтовый агент). Форма добавляется в документ посредством тэга form, который может располагаться внутри элемента body и вложенных в него элементов. В документе может быть несколько элементов form, но вложение одной формы в другую не допускается. Помимо общих для большинства элементов атрибутов, таких как id, class, style, элемент form имеет ряд специфических атрибутов. •
•
•
Атрибут action задает URL (адрес), на который будут отправлены данные для обработки. В приведенном примере данные будут отправлены на страницу myform.aspx, находящуюся на том же сервере и в той же папке, что и документ, содержащий форму. Если атрибут action опущен, то данные будут отправлены на документ, содержащий форму. Атрибут method задает способ передачи данных на сервер. Возможны два значения: o get – данные будут добавлены к URL, заданному в атрибуте action. o post – данные будут отправлены через стандартный канал. Атрибут enctype задает MIME (Multipurpose Internet Mail Extensions) тип отправляемого содержимого. Значение по умолчанию этого
атрибута application/x-www-form-urlencoded. Это значение подходит большинства случаев, но если требуется загрузить файл сервер, enctype="multipart/form-data" (и method="post").
для на
Элементы управления Элементы управления позволяют пользователю вводить данные с целью их дальнейшей отправки на обработку. Для того, чтобы данные были отправлены, 1. Элемент управления должен находиться внутри элемента form. 2. Элемент управления должен иметь атрибут name. Данные из элементов управления, не соответствующих любому из этих требований, отправлены на сервер не будут. Ваше сообщение: Всего три HTML-тэга, input, select, textarea и button, формируют все разнообразие элементов управления. Элемент input имеет 10 различных форм, select 2.
input type="text" Этот элемент создает в браузере однострочное поле текстового ввода. Ряд атрибутов контролируют поведение этого элемента • • •
• •
Атрибут size задает число видимых символов в поле ввода (при условии моноширинного шрифта) и, соответственно, ширину самого объекта. Атрибут maxlength ограничивает число вводимых символов. Атрибут readonly устанавливает, может ли пользователь изменять содержимое элемента. Атрибут не требует значения. Если атрибут присутствует, то пользователь не может вводить текст или менять содержимое другим способом, но может получать фокус ввода. Атрибут disabled делает элемент недоступным. Атрибут не требует значения. Если атрибут присутствует, то элемент отображается с серым фоном и не может получать фокус ввода. Атрибут value содержит текст, который будет отображаться в поле ввода, может изменяться пользователем и будет отправлен на сервер.
input type="password" Этот элемент аналогичен input type="text", но вводимые пользователем символы отображаются звездочками или точками, в зависимости от браузера.
input type="hidden" Как следует из типа, этот элемент не отображается в браузере, но хранит информацию, введенную в атрибут value на сервере или посредством Javascript на клиенте.
input type="checkbox" Элемент отображается в виде маленького (12х12px) окошка, при щелчке по которому появляется или исчезает галочка. Данные этого элемента управления отправляются на сервер, только если стоит галочка. Атрибуты элемента: • •
Атрибут value – это значение, которое будет отправлено на сервер, если стоит галочка. Если значение не задано, то по умолчанию "on". Атрибут checked задает, стоит ли галочка изначально. Атрибут не требует значения (для корректности XHTML значение должно быть checked).
input type="radio" Как правило, этот элемент используется в составе группы переключателей, в которой может быть выбран только один. Ваш возраст:
name="age" name="age" name="age" name="age"
value="1">10 – 15 лет value="2" checked>16 – 25 лет value="3">26 – 40 лет value="4">Старше 40 лет
Обратите внимание, что вся группа имеет одинаковое значение атрибута name. Атрибут checked задает начальный выбор. На сервер будет отправлено только значение выбранного элемента из группы.
input type="file" Этот элемент отображается как текстовое поле с расположенной рядом кнопкой "Обзор" (или имеющей аналогичный смысл, в зависимости от браузера), при нажатии на которую открывается окно выбора файла для отгрузки на сервер. Для того, чтобы отгрузка файла произошла, должны быть выполнены следующие условия: 1. 2. 3. 4.
Элемент Элемент Элемент Элемент
input type="file" должен находиться внутри элемента form. должен иметь атрибут name. form должен иметь атрибут method="post" form должен иметь атрибут enctype="multipart/form-data"
Отгружаемый файл должен быть принят и обработан на сервере.
input type="submit" Этот элемент отображается в виде кнопки, при нажатии на которую данные формы отправляются на сервер. Значение атрибута value используется как текст на кнопке. Если value не задано, текст на кнопке зависит от браузера ("Отправить", "Отправить запрос" и т.д.). Если в форме присутствует единственный элементinput type="submit", то нет необходимости задавать его атрибут name (и, соответственно, отправлять значение на сервер). Если элементов input type="submit"несколько, атрибут name позволит различить на сервере, какая кнопка была нажата. Если фокус пользовательского ввода находится в форме и пользователь нажимает клавишу Enter, это эквивалентно нажатию кнопки submit. Если таких кнопок несколько, срабатывает первая в форме, если только фокус ввода не находился на любой другой кнопке submit.
input type="image" Этот элемент позволяет заменить кнопку submit изображением, при нажатии на которое данные отправляются на сервер. Файл изображения задается в атрибутеsrc, альтернативный текст в атрибуте alt. При отправке на сервер значение атрибута value игнорируется, вместо этого отправляются x и y координаты щелчка мыши внутри изображения (imgSubmit.x=10 imgSubmit.y=15).
input type="reset" Этот элемент отображается в виде кнопки, при нажатии на которую данные формы возвращаются к заданным изначально без отправки на сервер. Значение атрибута value используется как текст на кнопке. Если value не задано, текст на кнопке зависит от браузера ("Очистить", "Reset" и т.д.).
input type="button" Этот элемент отображается в виде кнопки, нажатие на которую не производит никаких действий, если они не запрограммированы разработчиком формы (не обработано событие onclick элемента). Значение атрибута value используется как текст на кнопке.
Элемент button Элемент button является альтернативой кнопкам input type=submit, reset и button. Элемент имеет атрибуты name (для отправки данных на сервер), type со
значениями submit, reset и button и value (отправляемое на сервер значение). Между открывающим и закрывающим тэгами элемента button находится HTML-содержимое, которое отображается на кнопке.
Элемент select Этот элемент отображается как список опций или как раскрывающийся список, в зависимости от значения атрибута size. Внутри элемента располагаются опции и/или группы опций. <select name="fruits"> <select size="6" name="chemistry"> Пользователь может выбрать только одну опцию из раскрывающего списка. Значение (value) этой опции будет отправлено на сервер. Если атрибут valueотсутствует, передается текст опции. Список опций допускает множественный выбор, если к элементу select добавлен атрибут multiple. Атрибут multiple не требует значения (в XHTML значение, как обычно в таких случаях, совпадает с именем атрибута) и автоматически превращает элемент select в список опций независимо от наличия или значения атрибута size. Пользователь делает множественный выбор, удерживая клавишу Shift (опции подряд) или Ctrl (опции вразбивку). Выберите продукты для салата <select name="salad" multiple>
Элемент textarea отображается в браузере как поле для многострочного текстового ввода. Атрибуты cols и rows задают ширину (число символов) и высоту (число строк) элемента. Добавление атрибута readonly делает текст в поле доступным только для чтения. У элемента textarea нет атрибута maxlength или аналогичного, ограничивающего длину вводимого текста. Если ограничение необходимо, это следует делать программными средствами (см. ниже). В отличие от других элементов управления, нажатие клавиши Enter в textarea добавляет новую строку (в остальных случаях отправляет данные формы на сервер).
Вспомогательный элемент label Для облегчения доступа в форме связанный с элементом управления.
может
использоваться
элемент label (метка),
Щелчок по метке равноценен щелчку по элементу Атрибут for элемента label связан с id (не name) элемента управления.
управления.
Программный доступ к форме и ее элементам Форма является частью HTML-документа, и программный доступ к ее свойствам, методам и событиям осуществляется через Объектную модель документа (DOM), предоставляемую API браузера. API позволяет читать, изменять, удалять и создавать новые элементы формы. Все эти действия выполняются при помощи сценариев, написанных на языке Javascript (или VBScript). Доступ к форме (объекту form) осуществляется по индексу в коллекции форм HTMLдокумента. var oForm = document.forms[0];//первая форма в документе Internet Explorer допускает также доступ по имени формы (атрибуту name), если таковой присутствует. Согласно спецификации HTML 4.01, атрибут name элементаform считается устаревшим и поддерживается только для обратной совместимости. <script type="text/javascript"> var oForm = document.Form1;//работает в Internet Explorer Элемент form обладает множеством свойств, общих для большинства HTML-элементов, специфическими являются свойства action, method и enctype, совпадающие по смыслу с одноименными атрибутами; все они доступны по чтению и записи. Метод submit() немедленно отправляет данные формы на сервер. Метод reset() очищает все введенные пользователем данные без отправки на сервер. Важнейшими событиями, связанными с формой, являются onsubmit(пользователь
нажал кнопку Submit) и onreset (пользователь нажал кнопку Reset). Оба эти события могут быть перехвачены и обработаны. <script type="text/javascript"> function Validate(oForm) { //выполнить проверку данных формы return true; } Доступ к элементам управления формы осуществляется по их именам (атрибутам name). Возможен также поиск элементов управления (как и любых других HTML-элементов) по их id. Все элементы управления имеют свойства name, id, style, class (CSS) и некоторые другие, доступные по чтению и, в большинстве случаев, по записи (изменению). Свойство value (значение) есть у всех элементов управления, кроме input type="image". Именно это значение передается на сервер (при наличии атрибута name) при отправке данных формы. Общим для всех элементов управления является метод focus(), который передает фокус ввода элементу (и вызывает событие onfocus). Метод select()отличается от метода focus() тем, что не только помещает фокус ввода в элемент, но и, в случае текстовых полей, выделяет содержимое. Все элементы управления генерируют многочисленные события, которые могут быть перехвачены и обработаны программно. •
•
•
• •
Событие onfocus происходит, когда элемент управления получает фокус ввода, например, пользователь щелкает кнопкой мыши в текстовом поле или перемещается к элементу управления при помощи клавиши Tab на клавиатуре. В любой момент времени не более чем один элемент может иметь фокус ввода. Событие onblur происходит, когда элемент управления теряет фокус ввода, независимо, изменен элемент или нет. При переходе от одного элемента управления к другому сначала происходит событие onblur первого элемента, затем событие onfocus второго элемента. Событие onchange происходит, когда текстовое поле (элементы input type=text или password или textarea) или список опций (элемент select) были изменены пользователем и теряют фокус ввода. Это событие происходит до события onblur. Если изменений не было или они сделаны программно, событие не происходит. Событие onchange не происходит также, пока пользователь продолжает набирать текст или перемещаться по списку опций. Событие onclick генерируется, когда пользователь щелкает кнопкой мыши по элементу или нажимает клавишу Enter или пробел на кнопке, имеющей фокус ввода. Событие onkeypress генерируется, когда пользователь нажимает и отпускает клавишу, производящую символ, на клавиатуре. Это событие может быть разделено на два отдельных события, onkeydown (пользователь нажимает клавишу) и onkeyup (пользователь отпускает клавишу). Определить нажатую клавишу можно через объект event (событие), который генерируется Internet Explorer при возникновении события.
Следует помнить, что DOM модели, предоставляемые различными браузерами, различаются, и различия максимальны именно в обработке событий. Mozilla Firefox, Safari и Google Chrome отправляют в функцию – обработчик события аргумент – объект event> (событие). Internet Explorer не отправляет аргументы, но делает объект window.event доступным внутри функции – обработчика. Пример: проверка данных формы Рассмотрим обращение к объектной модели HTML-формы на примере проверки полноты введенных данных в регистрационную форму. XHTML 1.0 Transitional//EN" Регистрация <script type="text/javascript" src="form.js">
Стилевое оформление страницы можно поместить в отдельный файл (здесь form.css). Содержимое каскадной таблицы стилей может выглядеть, например, так: input[type="text"], input[type="password"] { border: solid 1px #ccc; width: 150px; } /* Использование псевдо-класса :focus - хорошая альтернатива обработке события onfocus */ input[type="text"]:focus, input[type="password"]:focus, input:focus+label /* Элемент label, следующий сказу за элементом, получившим фокус ввода */ { background:#cff; } /* Первая ячейка таблицы в строке */ td:first-child {text-align: right;} .Counter { position:absolute; display:none; font-size:small; background:#dfd; } table {border:solid 1px #ccc;} #errors {color:Red;}
Проверку правильности и полноты ввода данных осуществляет следующий сценарий, помещенный в файл form.js и подключенный к форме при помощи элемента script в элементе head. /* Объявляем переменную для формы. В этот момент мы не можем связать ее с объектом, поскольку документ еще не до конца загружен */ var oForm = null; /*
Объявляем функцию, которая будет вызываться при попытке отправить данные на сервер (пользователь нажал кнопку submit) */ function Validate() { // Очищаем результаты предыдущей проверки //Функция ClearErrors определена ниже ClearErrors(); var result = true; // результат проверки формы // Находим элемент, в который будут записываться ошибки var oErrors = document.getElementById('errors'); // и очищаем его содержимое oErrors.innerHTML = ''; //Проверяем Имя пользователя if (!oForm.username.value) {// В поле username ничего не введено // проверка не прошла result = false; //добавляем описание ошибки oErrors.innerHTML += '
Введите имя пользователя
'; // помечаем элемент oForm.username.style.borderColor = 'red'; //поместить фокус ввода в поле ввода и выделить все содержимое oForm.username.select(); } // в противном случае не делать ничего //Проверяем пароль if (!oForm.pwd.value) { oErrors.innerHTML += '
Введите пароль
'; oForm.pwd.style.borderColor = 'red'; if (result) {// элемент с ошибкой не был до этого найден oForm.pwd.select(); } result = false; } // Проверяем совпадение введенных паролей // Поле подтверждения пароля не имеет атрибута name, // поэтому мы не можем получить его через oForm.pwd1 // Используем поиск в документе по атрибуту id var oPwd1 = document.getElementById('pwd1'); if (!oPwd1.value) {// поле пусто oErrors.innerHTML += '
Подтвердите пароль
'; oPwd1.style.borderColor = 'red'; if (result) { oPwd1.select(); } result = false; } else // поле не пусто if (oPwd1.value != oForm.pwd.value) {// пароли не совпадают oErrors.innerHTML += '
Пароли должны совпадать
'; oPwd1.style.borderColor = 'red'; if (result) { oPwd1.select(); } result = false; } // Группа переключателей представляет собой массив элементов. // Мы должны проверить каждый var genderSelected = false; for (var i = 0, n = oForm.gender.length; i < n; i++) { if (oForm.gender[i].checked) {// найден выбранный элемент genderSelected = true; // нет необходимости продолжать break;// выход из цикла
} } if (!genderSelected) {// ни один из переключателей не выбран oErrors.innerHTML += '
Укажите пол
'; if (result) { // элемент input type=radio не имеет метода select() // помещаем фокус ввода в первый элемент группы oForm.gender[0].focus(); } result = false; } if (!oForm.agree.checked) { oErrors.innerHTML += '
Вы должны согласиться с условиями
'; if (result) { // элемент input type=checkbox не имеет метода select() // помещаем фокус ввода в этот элемент oForm.agree.focus(); } result = false; } // Проверка закончена. // Если result == false, отправка данных отменяется return result; }// function Validate //вспомогательная функция очистки формы function ClearErrors() { // Находим элемент, в который записываются ошибки var oErrors = document.getElementById('errors'); // и очищаем его содержимое oErrors.innerHTML = ''; oForm.username.style.borderColor = ''; oForm.pwd.style.borderColor = ''; document.getElementById('pwd1').style.borderColor = ''; } // Функция, которая автоматически вызывается // по окончании загрузки документа в окно браузера window.onload = function() { // документ загружен, и мы можем найти внем форму. oForm = document.forms[0]; // Событие onkeyup происходит, когда пользователь // отпускает клавишу в поле текстового ввода oForm.username.onkeyup = oForm.pwd.onkeyup = document.getElementById('pwd1').onkeyup = function() {// футкция обрабатывает событие любого из трех элементов // this является ссылкой на элемент, который вызвал событие // id вспомогательных элементов сделаны так, чтобы легко вычислись // из имени элемента-источника события //если атрибут name отсутствует или пуст, //будет использован id (this.name || this.id) var elem = document.getElementById('span' + (this.name || this.id)); elem.innerHTML = this.value.length + ' из ' + this.maxLength; elem.style.display = 'inline'; }; // onkeyup // Событие onblur происходит, когда элемент теряет фокус ввода oForm.username.onblur = oForm.pwd.onblur = document.getElementById('pwd1').onblur = function() { var elem = document.getElementById('span' + (this.name || this.id));
// активируем ввод в поле Имя пользователя oForm.username.focus(); // window.onload
Подобную проверку рекомендуется производить во всех случаях, когда ожидается ввод со стороны пользователя, однако она не заменяет и не отменяет необходимости выполнить еще одну проверку на стороне сервера. Фактически, проверка данных в браузере делается лишь для удобства пользователя (убедиться, что необходимые данные введены и отвечают формальным требованиям) и уменьшения сетевого трафика (заведомо ошибочные данные не будут отправлены на сервер). Ни в коем случае нельзя проверять в браузере имя пользователя и его пароль – только наличие таких данных.
Безопасность форм Неправильное использование HTML-форм может существенно повредить безопасности веб-приложения. Данные формы, передаваемые через HTTP протокол, не шифруются и могут быть перехвачены и изменены при передаче. Для передачи конфиденциальных данных, таких как имена пользователей, пароли, номера кредитных карточек и т.д., следует использовать HTTPS (Secure Hypertext Transfer Protocol). Это поможет обезопасить данные ваших пользователей. С другой стороны, недобросовестный пользователь может пытаться использовать вашу форму для нарушения работы веб-приложения или кражи информации с сервера. Фактически, веб-страницы доступны неопределенно большому числу лиц, и наиболее безопасно рассматривать каждый запрос к серверу как потенциальное покушение на его безопасность (пусть даже это противоречит презумпции невиновности). С практической точки зрения, следует 1. ограничивать и проверять длину данных, вводимых в текстовые поля (input type="text", input type="password", textarea). 2. ограничивать пользовательский ввод только допустимыми символами (например, буквами и цифрами), не допуская тэгов и специальных символов. 3. иметь в виду, что проверка данных на стороне клиента (в браузере) служит лишь для удобства пользователя и может быть достаточно легко отключена.
Вопросы 1. 2. 3. 4. 5. 6. 7.
Что такое HTML-форма? Для чего она предназначена? Какие специфические атрибуты имеет форма? Данные каких элементов управления отправляются на сервер? Перечислите и охарактеризуйте элементы управления формы. Перечислите и охарактеризуйте атрибуты элемента текстового ввода. Как получить программный доступ к объекту form? Перечислите основные методы и события объекта form.
18. Лабораторная работа: Создание формы с динамической проверкой Пользуясь примером, описанным в лекции 17 , создайте самостоятельно веб-страницу с формой, содержащей проверку вводимых данных (пример относительно прост и проверяет только наличие введённых данных, а также делает подсказки по мере ввода о количестве символов). 19. Лекция: Внедрение объектов в документ HTML Возможности и недостатки динамических HTML-страниц. Применение технологий Java, Flash, SVG, AJAX, Silverlight (обзор) Содержание • •
Технология JAVA Adobe Flash и Scalable Vector Graphics
o o • • •
Adobe Flash Scalable Vector Graphics (SVG)
AJAX (Асинхронный Javascript с XML) Microsoft Silverlight Вопросы
Как было показано в предыдущих лекциях, динамический HTML (под которым обычно подразумевают комплексную технологию работы с объектной моделью HTML-документа при помощи Javascript и CSS) позволяет превратить статические веб-страницы в интерактивные приложения. Можно "на лету" создавать и изменять любые элементы документа, можно реагировать на любые действия пользователя с документом. Теперь рассмотрим то, чего достичь средствами DHTML не удастся: • • • •
работать с графикой - создавать и изменять векторные (или точечные) изображения; работать с медиа-контентом - воспроизводить аудио и видео (существующие решения используют посторонние по отношению к DHTML и браузеру технологии); сохранять данные в файловой системе пользователя для последующего использования приложением (за исключением весьма ограниченных по своим возможностям cookies); поддерживать непрерывную связь с сервером (что, в принципе, достижимо средствами Javascript и iframe, но, как правило, осуществляется при помощи технологий, описываемых далее).
Однако тенденция сделать приложения, выполняемые в браузере, полноценными, весьма сильна. С одной стороны, браузер для пользователя - это окно в информационный мир, и желательно, чтобы вид из него был максимально реалистичным и в то же время насыщенным разнообразными удобствами ИТцивилизации (виртуальный полет над Землей - хороший пример). С другой стороны, поскольку браузеры становятся все более сложными программами и в перспективе, вероятно, станут поддерживать огромное разнообразие форматов приема и выдачи информации, то для разработчиков становится удобным ориентироваться именно на браузер как средство взаимодействия с пользователем. Существует и специальный термин для определения таких приложений - Rich Internet Applications (переведем это как "роскошные интернет-приложения"), сокращенно RIA. В этой лекции мы рассмотрим, какие средства существуют для преодоления указанных недостатков за рамками HTML и CSS, а в следующей - как будут эволюционировать
сами эти две технологии для преодоления собственных недостатков в ближайшем будущем. Вообще, технологий расширения возможностей браузера создано очень много, и едва ли кто-нибудь сможет перечислить все: развитие не всегда шло централизованно, несмотря на существование консорциума WWW. Рассмотрим из них лишь самые основные, ключевые, имеющие практическую ценность на сегодняшний день.
Технология JAVA Правильнее говорить о мире технологий Java: разработчики шутят, что, составив любую трехбуквенную аббревиатуру на J, вы с высокой вероятностью получите название одной из технологий, основанных на языке Java. Но здесь пойдет речь только о тех, которые запускаются в браузере, а это, в первую очередь, Java-апплеты. Сам язык Java появился в начале 90-х годов прошлого века внутри компании Sun Microsystems, занимающейся, в частности, разработкой программного обеспечения. Целью его авторов было создание альтернативы C++ - языку, бескомпромиссному по эффективности работы программ, но и требующему чрезвычайно аккуратной работы программиста, что не всегда оправдано. Язык Java берет за основу проверенные временем приемы объектно-ориентированного программирования в C++, исключая те языковые механизмы, которые дают возможность программистам допускать наиболее разрушительные и трудноуловимые ошибки (в первую очередь это арифметика указателей, явное управление памятью и множественное наследование). Была добавлена языковая поддержка многопоточности и распределенных вычислений, созданы многочисленные библиотеки. С 1996 года поддержку Java включила в свой (тогда - самый популярный) браузер компания Netscape. В настоящее время "Java повсюду" - в бытовой электронике, мобильных устройствах и, конечно, в вебприложениях - как на серверной, так и на клиентской стороне. Java-апплет - это программа, которая выполняется виртуальной машиной Java и отображается в окне браузера. С понятием "виртуальная машина" связана одна из ключевых идей Java: программа, написанная на этом языке, компилируется не в набор инструкций какого-либо конкретного процессора, а в специальный байт-код. Для запуска байт-кода на компьютере (или другом устройстве с вычислительными возможностями) должна быть установлена операционная среда (Java Runtime Environment), которая компилирует байт-код уже в "родные" (native) инструкции локального процессора. Главная привлекательная особенность такого подхода заключается в том, что программисту не нужно заботиться о кроссплатформенности своего приложения - эту заботу берет на себя операционная среда, реализованная для всех популярных платформ (Windows, Mac, Linux и т.д.). Операционная среда Java Runtime Environment распространяется бесплатно и используется для всех видов Javaприложений (а не только веб-приложений), поэтому она распространена достаточно хорошо. Чтобы вставить апплет в веб-страницу, нужно применить еще один особый механизм HTML. Основная точка расширения HTML -это внедрение в документобъектов. Здесь "объект" - абстракция: он означает "все что угодно, если браузер сможет обработать это - возможно, при помощи дополнительной программы". В частности, Java-апплеты обрабатываются Java-плагином и виртуальной машиной Java. Старый, но простой и неплохо работающий способ вставки апплета - использование элемента applet:
Браузер, обрабатывая такой элемент, создаст для апплета в документе прямоугольник 600*400 точек и запустит файл "AppletExample.class" (где находится байт-код) при помощи Java-плагина. Элемент applet, однако, признан устаревшим, и взамен его стандартом HTML 4 рекомендован более универсальный элемент object (пригодный в принципе для любого содержимого, а не только для Java-апплетов). Правда, в его интерпретации между современными браузерами имеются разночтения - в первую очередь, разнится способ идентификации типа объекта (classid): Приведенная сравнительно громоздкая конструкция действительно неизбежна, если мы хотим следовать стандарту и в то же время не игнорировать нестандартное поведение браузера Internet Explorer. В примере элемент object вложен в другой элемент object. Дело в том, что, согласно стандарту, браузер, если он не в состоянии отобразить объект, то отображает его вложенное содержимое. В данном случае, если внешний объект отобразить не удается, то отображается внутренний; а если же и это невозможно, то отображается текст со ссылкой на страницу загрузки JRE. Кстати, байт-код может быть размещен в Java-архиве (jar), и в этом случае разметка несколько изменится. Приведем здесь пример простейшего апплета. Не ставя перед собой цели научить программировать на Java или Flash, мы все же считаем, что начинающий вебразработчик должен быть сразу верно сориентирован в многообразном и запутанном мире интернет-технологий - необходимо иметь представление о ключевых технологиях, их возможностях и знать, как начать путь по их изучению и что ждет на этом пути. 1 import java.applet.*; 2 import java.awt.*; 3 import java.awt.geom.Ellipse2D; 4 5 public class AppletExample extends Applet { 6 @Override 7 public void paint(Graphics g) { 8 Graphics2D g2 = (Graphics2D) g; 9 g2.setPaint(new GradientPaint(0, 100, Color.WHITE, 300, 600, Color.RED)); 10 g2.fill(new Ellipse2D.Double(0, 100, 600, 200)); 11 12 g2.setColor(Color.BLUE); 13 g2.setFont(new Font("Arial", Font.ITALIC, 60)); 14 g2.drawString("Здравствуй, мир!", 140, 210);
Нетрудно видеть, что непосредственно функционирование апплета описано в строках 9 - 14. Код апплета устанавливает для заливки двухцветный градиент - от белого в точке (0; 100) до красного в точке (300; 600), затем заполняет им эллипс, вписанный в прямоугольную область с левым верхним углом в (0; 100), шириной 600 и высотой 200 пикселов. И наконец, выводит надпись "Hello, World!" начиная с точки (140; 210) синим курсивом гарнитуры Arial и кеглем высотой 60 пунктов. С точки зрения же структуры приведенного Java-кода (он должен быть сохранен в файле "AppletExample.java"), мы имеем пользовательский класс AppletExample, расширяющий стандартный класс Applet. В нем переопределяется (@Override) метод paint, т.е. метод рисования на экране. Метод принимает в качестве входного параметра объект типа Graphics, играющий роль холста для рисования и интерпретирует его как объект типа Graphics2D (который умеет больше, чем более старый класс Graphics - в частности, делать градиентную заливку и регулировать толщину линий). Используемые библиотеки перечислены в директивах import в самом начале кода.
Рис. 19.1. Развертывание апплета JAVA на клиентском компьютере
Для выполнения апплета на клиентском компьютере, как уже говорилось, необходима среда Java Runtime Environment (JRE). Для разработки и компиляции апплетов (и других Java-приложений) необходим Java Development Kit (JDK), также распространяемый бесплатно. Когда JDK установлен, то для компиляции, например, файла примера "AppletExample.java" достаточно выполнить такую команду: "C:\Program Files\Java\jdk1.6.0_18\bin\javac.exe" AppletExample.java (номер версии JDK установленному).
При этом компилятор создаст файл AppletExample.class, который можно подключать к HTML-документу одним из показанных ранее способов. Удобнее, конечно, работать не в командной строке, а в интегрированной среде разработки (IDE). Для этого вместе с JDK (по желанию пользователя) может быть загружена NetBeans IDE. Среда JRE включает в себя компоненты самого широкого назначения, поэтому возможности апплетов практически не ограничены (за исключением, конечно, соображений безопасности). Сюда входит и графика (в том числе трехмерная!), и пользовательские формы, и доступ к данным, и разнообразные вычисления. Упражнение. Загрузите последнюю версию JDK с 19.http://java.sun.com/javase/downloads/index.jsp . Создайте, скомпилируйте и включите в HTML-страницу апплет, рисующий еще несколько простых фигур. Примеры см. на19.http://java.sun.com/docs/books/tutorial/2d/index.html. Если вы проделали предыдущее упражнение, то почувствовали, что "рисование" не очень-то похоже на рисование - на самом деле это чистое программирование. При таком подходе либо дизайнер должен уметь программировать в рамках той или иной технологии, либо программист обладать тонким художественным вкусом: разделение труда пропадает. Такое положение дел давно уже не считается нормальным, и все продвинутые информационные технологии обязательно предоставляют средства разделения содержания, представления и поведения, а также разделения труда соответствующих специалистов. Так разделены HTML, CSS и Javascript. Аналогичные разделения существуют и во всех рассматриваемых в данной лекции технологиях - как правило, это основанная на XML разметка + CSS-подобные стили + программный код. Рассмотрим еще одну Java-платформу, имеющую прямое отношение к данному курсу: JavaFX - программная платформа для создания RIA. Программа, написанная на JavaFX Script, компилируется специальным компилятором в байт-код и подключается к HTML-документу как апплет. Приведем небольшой пример. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Stop { color : Color.BISQUE offset: 0.0 }, Stop { color : Color.BLUE offset: 1.0 }, ] } } Text { fill:Color.MAGENTA font : Font { size: 24 } x: 70, y: 60 content: "Java FX" } ] }
Этот код, напоминающий JSON (нотацию объектов Javascript) описывает рабочую область 600*400 пикселов с эллипсом и надписью. Интересно то, что декларативная нотация JavaFX Script позволяет единообразно описывать графические элементы, элементы ввода данных и анимацию. Вводить код в NetBeans IDE помогает палитра компонентов; окно предварительного просмотра отображает результат. Предусмотрена возможность генерировать разметку графических объектов из чисто графических приложений - Adobe Photoshop, Illustrator и SVG-редакторов (через вспомогательный конвертер). Поддерживаются таблицы стилей.
Рис. 19.2. Разработка JavaFX-приложения в среде NetBeans К недостаткам JavaFx можно отнести невозможность распространения таких приложений без подключения к Интернет. По этой причине мы не включаем сюда работающий пример, а вместо этого даем ссылку на первоисточник: http://javafx.com/ru/about/overview/.
Adobe Flash и Scalable Vector Graphics Adobe Flash
Еще одна хорошо известная платформа для веб-приложений. После Java-апплетов понять Flash-приложения довольно легко: это тоже программы, компилируемые в байткод (файл swf) и запускаемые на клиентском компьютере виртуальной машиной - Flash Player. Аналогия полная. Разница в том, что Flash-приложения - это именно вебприложения, т.е. они более специализированы. Возможно, поэтому размер дистрибутива Flash Player примерно на порядок меньше размера дистрибутива JRE. Проигрывая апплетам в универсальности, Flash выигрывает с точки зрения типичных, первоочередных потребностей веб-разработчиков и пользователей Интернет. Пользователям нужно, чтобы веб-приложение запускалось быстро, а если для этого нужен какой-то плагин, то желательно, чтобы он загружался и устанавливался тоже быстро. Во всем этом Flash превосходит более тяжеловесную Java. Нужны и гарантии безопасности клиентской машины от вредоносных приложений - Flash более ограничен и, соответственно, безопасен. Разработчикам нужна, во-первых уверенность в том, что их приложения не останутся незамеченными из-за отсутствия у клиента необходимого плагина. Flash Player установлен в настоящее время примерно у 99% пользователей Интернет, JRE - у несколько меньшего количества пользователей (80-90% по разным оценкам). Кроме того, для быстрой разработки приложений очень нужен полноценный WYSIWYG-редактор - таким является Adobe Flash Professional. Для Java-приложений, конечно, существует целый ряд профессиональных IDE, которые предоставляют много полезных возможностей разработчикам. Однако веб-приложения презентационного и интерактивного характера, которые мы привыкли уже видеть на Flash, на JavaFx создавать пришлось бы старым, невизуальным способом - полноценного редактора для таких задач пока нет. Впрочем, нельзя сравнивать коммерческую среду разработки Adobe Flash Professional с бесплатными NetBeans и Eclipse. Для работы с Flash-технологией вообще нет бесплатной среды разработки, содержащей хотя бы отладчик. Бесплатный SDK, однако относительно недавно появился - это Adobe Flex SDK, который позволяет теперь строить Flash-приложения на основе XML-подобной разметки (MXML) с поддержкой CSS-стилей и программного кода на объектно-ориентированном языке ActionScript. Ниже показан пример разметки, включающей Flash-содержимое в HTML-документ и диаграмма (рис. 19.3), описывающая развертывание необходимых для работы Flashприложения артефактов на клиентском компьютере. <param name="allowScriptAccess" value="sameDomain" /> <param name="movie" value="FlashExample.swf" /> <param name="loop" value="false" /> <param name="menu" value="false" /> <param name="quality" value="high" /> <param name="play" value="false" />
Рис. 19.3. Развертывание Flash-приложения на клиентском компьютере Говоря о Flash, нельзя не добавить, что эта технология в настоящее время переросла рамки веб-приложений, и позволяет создавать кроссплатформенные приложения, выполняемые за пределами браузера - при помощи среды Adobe Integrated Runtime (AIR). Аналогия с Java продолжается.
Scalable Vector Graphics (SVG) Язык разметки векторной графики был разработан консорциумом WWW и появился в виде спецификации в 2001 году. Этот язык, основанный на XML, позволяет описывать двумерные изображения, содержащие элементы анимации и интерактивности. Поддерживаются стили CSS и сценарии Javascript. Привлекательность SVG - в простоте создания графики и ее включения в HTMLдокумент. <svg version="1.1" xmlns="http://www.w3.org/2000/svg"> <defs> <stop offset="5%" stop-color="#F60" /> <stop offset="95%" stop-color="#FF6" /> <ellipse cx="250" cy="200" rx="200" ry="200" fill="url(#MyGradient)"/> Здравствуй, мир!
Пример 19.3. Определение графических элементов на SVG и включение SVG-объекта в HTML-документ (результат - на рис. 19.4) (html, txt)
Рис. 19.4. Пример HTML-страницы с SVG Как видно из примера 19.3, SVG-документ представляет собой XML-документ с соответствующим ОТД. В корневой элемент документа svg вложены определения градиента, эллипса и текстового блока, представляющие собой элементы, напоминающие элементы XHTML. Этот код можно написать в обычном текстовом редакторе, а можно воспользоваться и WYSIWYG-редактором векторной графики: большинство таких редакторов поддерживает экспорт в SVG, и существуют специализированные SVG-редакторы (в том числе бесплатные). Включение объекта в HTML-документ также происходит обычным образом - при помощи универсального элемента object. Некоторые браузеры поддерживают непосредственную интеграцию SVG-разметки в HTML-документ.
Самая большая проблема SVG - отсутствие поддержки браузером IE. Для отображения SVG в IE используется либо плагин (например, Adobe SVG Viewer), либо апплет (проект Batik), либо Flash-приложение (проект SVGWeb).
AJAX (Асинхронный Javascript с XML) Идея этой технологии чрезвычайно проста и продуктивна: браузер может отправлять запрос серверу не только синхронно(отправил - дождался ответа - показал на экране), но и асинхронно (отправил, не прерывая работу в текущем режиме - получил ответ показал на экране). Простой жизненный пример асинхронного запроса привести легко. Например, вы говорите попутчику: "Разбуди, когда прибудет поезд". После этого вы не будете ждать, пока он начнет вас будить, а спокойно ляжете спать. Пример синхронного запроса в жизни (т.е. когда вызывающая сторона не предпринимает ничего, пока не получит ответа) придумать сложнее - видимо, асинхронность более естественна для нас. Примеры веб-приложений, где асинхронные запросы не заменимы синхронными: • •
Интерактивные карты. Формы с подгрузкой данных в фоновом режиме.
Приведем простой пример: на веб-странице требуется отобразить информацию о курсе валют. Немного усложним задачу тем, что пользователь может пожелать узнать курс не только на сегодняшнюю, но и на любую прошедшую дату - это позволит лучше проиллюстрировать AJAX. Получение курсов валют
Transitional//EN"
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jqueryui.min.js"> <script type="text/javascript"> window.onload = function() { $("#datepicker").datepicker({ onSelect: GetData, dateFormat: 'dd/mm/yy' }); }; function GetData(date) { $.get("http://www.cbr.ru/scripts/XML_daily.asp", { date_req: date }, function(data) { var result = data.text.replace(/\w+ \w+ 1/g, ' 1'); $('#Valutes').html(result); }); }
Внимание. Данный пример работает компьютера (а не с веб-сервера).
только
будучи
запущенным
с
локального
Код примера лаконичен. В теле HTML-документа присутствует поле ввода для даты datepicker и пустой контейнер Valutes для результатов запроса. Разбор скрипта легче начать с функции GetData(date), которая запускается в тот момент, когда дата выбрана. Что нужно сделать в этот момент? Отправить асинхронный запрос по определенному Интернет-адресу (в данном примере использована вебслужба Центробанка РФ), передав в качестве параметра выбранную дату. Когда будет получен ответ - отобразить его в секции Valutes. Вся эта работа выполняется при помощи функции $.get библиотеки JQuery (можно было бы проделать все и на "чистом" Javascript, без дополнительных библиотек, но код стал бы на порядок более громоздок и менее очевиден). Первый параметр функции $.get - URL, по которому следует сделать запрос (по умолчанию запрос - асинхронный). Второй параметр - объект, объединяющий параметры запроса. В данном примере это дата, а имя параметра - date_req (так установила техническая служба Центробанка). Последний параметр особенно интересен: это функция обратного вызова (callback function). Это и есть способ уведомить клиента о том, что сервер прислал ответ. В жизни есть масса примеров, когда мы назначаем кому-либо функцию обратного вызова по окончании продолжительного действия. "Вспомнишь - позвони": здесь функция обратного вызова - "телефонный звонок". "Приедем - разбуди": функция обратного вызова - "пробуждение", и т.п. В качестве последнего параметра указано определение функции, принимающей параметр data (это ответ сервера), делающей небольшое улучшение формата текста ответа (data.text) и выводящей его в секцию Valutes. Для удобства выбора даты в данном примере использован объект datepicker (календарь) библиотеки JQuery UI (еще в ней имеется масса полезных визуальных компонентов, которые легко встраиваются в HTML-документы). Примечательно, что с календарем связано еще две функции обратного вызова. Вопервых, командаwindow.onload = function() {...} равносильна следующему указанию для браузера: когда содержимое данного окна полностью загрузится, сделай вот что: ... . И далее идет команда привязки объекта datepicker к полю ввода. Вовторых, объект datepicker имеет событие onSelect ("дата выбрана"). Присваивая ему значение GetData, мы тем самым вновь устанавливаем обратный вызов: "Когда пользователь выберет дату, надо будет вызвать функцию GetData".
С точки зрения пользователя асинхронность запроса к веб-службе означает, что, пока запрос выполняется, можно продолжать работу со страницей - ее чтение или заполнение формы. Можно заметить, что в HTML-коде примера нет тэга . В основе технологии AJAX лежит объект XMLHttpRequest, который всегда создается из Javascript-кода. Подробное рассмотрение этого объекта выходит за рамки лекции. Достаточно сказать, что он "умеет" отправлять запрос серверу, отслеживать состояние запроса и делать обратный вызов по завершении запроса. Библиотека JQuery делает работу с XMLHttpRequest более лаконичной и независимой от браузера. Упражнения. Предположим, что на рассматриваемой веб-странице имеется секция со скрытым (visibility:hidden) анимированным gif-изображением переворачивающихся песочных часов. В момент отправки запроса на сервер часы нужно показать (что будет означать "ожидаем результат"), а при поступлении ответа - скрыть. Куда вставить команды отображения/скрытия изображения? Придумайте, как усовершенствовать код, чтобы ответы сервера сохранялись в Javascript-объекте, и на повторные запросы с одинаковой датой ответы извлекались бы из этого объекта, а не принимались с сервера. Подсказка: в качестве ключа для сохранения данных в объекте используйте строку, представляющую дату.
Microsoft Silverlight Если история Flash уходит корнями в середину 1990-х, то технология Microsoft Silverlight появилась совсем недавно - в 2007 году и во многом учитывает недостатки своих предшественников в области RIA-технологий. Идея, в целом, та же: специальный плагин выполняет приложение, интегрированное в веб-страницу при помощи элемента object. В реализации основное отличие, пожалуй, следующее: для разработки Silverlight-приложения используются языки достаточно широкого назначения. Кроме того, в Silverlight решена задача отделения содержания от поведения: для определения первого используется разметка (XAML), а для второго код на языке программирования из семейства .NET (в первую очередь, C# или Visual Basic). XAML (Extensible Application Markup Language - расширяемый язык разметки приложений) - еще один язык разметки,основанный на XML. XAML используется для создания графических интерфейсов нового поколения Windows-приложений, основанных на WPF (Windows Presentation Foundation). Семейство языков .NET интересно тем, что оно включает современные объектноориентированные языки с массой усовершенствований по сравнению с классическими C++ и Java. Также впечатляет количество библиотек, входящих в .NET Framework, которая бесплатно поставляется Microsoft и выполняет роль каркаса, берущего на себя компиляцию, запуск и обеспечение .NET-приложений необходимыми функциями. Silverlight-приложения тоже имеют доступ ко многим библиотекам .NET (которые поставляются в урезанном виде вместе с плагином Silverlight), что позволяет разработчику использовать массу преимуществ этой технологии. В результате Silverlight-разработчик получает платформу для своих приложений не менее эффективную, чем Flash, и, хотя не столь универсальную, как Java, но довольно продвинутую в этом отношении. На рис. 19.5 показано, какие компоненты взаимодействуют при работе Silverlightприложения. Как видно из рисунка, HTML-страница должна включать элементobject с типом содержимого application/x-silverlight-2 (номер версии может меняться). Объект реализует некоторую разновидность пользовательского элемента управления
(UserControl) и хранится в скомпилированном виде в файле SilverlightApp.xap (имя файла, разумеется, может быть произвольным, лишь бы оно было указано в значении параметра элемента object с именем source).
Рис. 19.5. Развертывание Silverlight-приложения на клиентском компьютере Для разработки Silverlight-приложений предназначен, в первую очередь, пакет Microsoft Expression, включающий приложение Microsoft Expression Blend (рис. 19.6).
Рис. 19.6. Работа с приложением Microsoft Expression Blend Пользователь Microsoft Expression Blend имеет возможность визуально в окне конструктора формировать интерфейс WPF- или Silverlight-приложения, создавая объекты, настраивая их свойства и определяя анимации. Интерфейс описывается XAML-разметкой, которую Blend формирует автоматически (или наоборот, если написать XAML-код в окне исходного кода, то в окне конструктора отобразятся соответствующие объекты). С каждым файлом XAML связан файл кода на Visual Basic или C#, в котором могут содержаться методы, манипулирующие объектной моделью приложения. Изучение C# выходит за пределы данного курса, однако дизайнер может создавать относительно простые Silverlight-приложения и не зная этого языка, и поэтому мы предлагаем познакомиться с этой перспективной технологией более подробно, проделав лабораторную работу. Подводя итоги лекции, следует ответить на естественно возникающий вопрос: какую же технологию следует брать на вооружение начинающему веб-дизайнеру? Несомненно то, что в рамках любой из рассмотренных технологий можно достичь интересных результатов, равно как и то, что области применения апплетов, Flash-приложений, SVG-графики, AJAX-страниц и приложений Silverlight далеко не совпадают. Нельзя, однако отрицать значение такого фактора как обилие справочной информации, литературы (в том числе на русском языке) и доступных версий программного обеспечения - здесь в настоящее время лидируют технологии Microsoft.
Вопросы 1. 2. 3. 4. 5.
Каких возможностей недостает в DHTML? Что такое Java-апплет? Как вставить апплет в веб-страницу? Каковы возможности и недостатки апплетов? В чем преимущества технологии Flash? Что из себя представляет документ SVG?
6. В чем основная идея технологии AJAX? Каковы ее применения? 7. Как применяются в AJAX-приложениях функции обратного вызова? 8. В чем заключаются особенности технологии Microsoft Silverlight?
20. Лабораторная работа: Знакомство с Silverligh Цель. Знакомство с программой Microsoft Expression Blend. Создание анимированной Silverlight-заставки и размещение её в HTML-документе Содержание •
Часть 1. Создание приложения с навигационным фреймом
1. Создание навигационной страницы. 2. Добавление текстового блока и стиля. 3. Проверка: запуск приложения в браузере
Часть 3. Создание анимации перемещений объектов
o o o
1. Создание элемента StoryBoard 2. Запись анимации 3. Запуск анимации.
Для данной лабораторной работы понадобится программа Microsoft Expression Blend версии не ниже третьей, пробную версию которой (на 60 дней) можно загрузить на официальном сайте. Для студентов пакет Microsoft Expression в настоящее время предоставляется бесплатно (см. http://dreamspark.ru).
Часть 1. фреймом
Создание
приложения
с
навигационным
1. Создание Silverlight-приложения Запустите Microsoft Expression Blend и создайте новый проект (File - New Project). Назовите проект Lab7 (рис. 20.1).
Рис. 20.1. Создание нового проекта в Blend Рассмотрим содержимое только что созданного проекта (рис. 20.2).
Рис. 20.2. Окно редактора Blend со вновь созданным проектом Прежде всего заметим, что рабочее пространство (Workspace), которое, в частности, определяет взаимное расположение панелей, может быть организовано в Blend одним из двух предустановленных способов - Design Workspace и Animation Workspace
(переключается через меню Window - Workspaces). Снимки экрана, иллюстрирующие данную работу, сделаны в Design Workspace, поэтому рекомендуем выбрать именно его. Сейчас проект представляет собой каталог на диске, содержащий ряд файлов, из которых главным для нас является MainPage.xaml - в нём размещена XAML-разметка основного содержимого приложения. Как видно в окне кода, содержимое состоит из элемента UserControl, среди атрибутов которого - ширина и высота рабочей области приложения, и вложенного в него элемента Grid с атрибутом x:Name="LayoutRoot" (это его уникальное имя, которое отображается в дереве объектов) - пустой таблицы из одной ячейки с белым фоном. Особое внимание обратите на дерево объектов - в нём все имеющиеся объекты показаны по имени, с учётом взаимной вложенности и Zуровня (что ниже в дереве, то выше над плоскостью экрана). Объекты можно найти здесь даже в том случае, когда их не видно в окне конструктора (если они, например, полностью прозрачны, невидимы, позиционированы далеко за границы рабочей области или просто потерялись во множестве других объектов). Когда объект выделен, панель Properties позволяет редактировать все его свойства. Наиболее активно в данной работе будут применяться панель Properties, дерево объектов, а также панель Timeline (до которой дело дойдёт немного позже).
2. Добавление навигационного фрейма Работа будет состоять из набора независимых друг от друга примеров, иллюстрирующих несколько простых, но мощных возможностей Silverlight. Удобно воспользоваться такой возможностью Silverlight как навигационная структура: в ней приложение содержит набор страниц (как веб-узел), переходить между которыми можно по гиперссылкам или кнопкам Вперёд - Назад браузера (каждая имеет и свой уникальный путь в адресной строке). При этом, естественно, страницы разрабатываются независимо. Добавим в приложение навигационный фрейм и ряд страниц. Поскольку размер страниц, создаваемых Blend, по умолчанию равен 640*480 пикс, для удобства дальнейшей работы сразу расширим окно приложения так, чтобы в нём свободно помещался навигационный фрейм указанного размера и общий заголовок. Выделите элемент UserControl в дереве объектов, найдите на панели Properties вкладку Layout, при необходимости разверните её, и установите размеры элемента равными 800*600 пикс (рис. 20.3).
Рис. 20.3. Установка размеров рабочей области Теперь добавим навигационный фрейм. Найдите элемент Frame на вкладке Controls панели Assets, перетащите его в окно конструктора, перейдите на панель свойств (фрейм будет выделен автоматически, поэтому его не надо сейчас выбирать в дереве объектов) и установите размеры фрейма равными 640*480 пикс (стандартный размер страницы), а также позиционируйте его внизу по центру, предварительно обнулив отступы (рис. 20.4).
Рис. 20.4. Добавление навигационного фрейма, настройка его размеров и положения Кроме того, имеет смысл обнулить толщину рамки фрейма (BorderThickness) на вкладке Appearance во избежание малейших отличий размера внутренней области фрейма от размера страницы (что может привести к странным для новичка эффектам при сжатии ячейки таблицы на странице).
3. Градиентная заливка. Выделите в дереве объектов элемент LayoutRoot и примените к нему какую-нибудь градиентную заливку (в светлых тонах). Для этого на вкладке Brushes панели Properties выберите в качестве способа заливки Gradient brush и для обеих позиций градиента (маркеры внизу) задайте по цвету (рис. 20.5).
Рис. 20.5. Установка заливки Далее, выбрав инструмент Gradient Tool с панели инструментов, направление цветового градиента примерно на 45 градусов (рис. 20.6).
поверните
Рис. 20.6. Настройка направления градиента цвета
4. Добавление текста. Выберите в дереве объектов LayoutRoot и на панели инструментов сделайте двойной щелчок по TextBlock. Добавится блок текста. Чтобы увидеть его достаточно крупно в окне конструктора, используйте масштабирование (вращение колеса мыши) и панорамирование (перетаскивание холста при выбранном инструменте Pan - в большинстве режимов, за исключением редактирования текста, панорамирование легко временно включить нажатием пробела). Введите произвольную строку заголовка и
щёлкните мышью за пределами блока - его размер будет подобран автоматически. Затем позиционируйте его вверху по центру и сделайте достаточно крупным, установив размер шрифта на вкладке Text панели Properties и применив начертание Bold. Выберите подходящий цвет на вкладке Brushes. К редактированию текста можно всегда вернуться, выбрав инструмент TextBlock.
Часть 2. Добавление страницы и стиля 1. Создание навигационной страницы. На панели Projects щёлкните правой кнопкой мыши по имени приложения и выберите из контекстного меню команду Add New Item (добавить новый элемент к проекту).
Рис. 20.7. Добавление нового элемента к проекту В открывшемся окне выберите Page в качестве добавляемого элемента, дайте странице имя AnimatePosition и нажмите OK (рис. 20.8).
Рис. 20.8. Создание навигационной страницы Добавленная страница содержит таблицу LayoutRoot без заливки.
2. Добавление текстового блока и стиля. На странице AnimatePosition будет размещено несколько крупных текстовых блоков, которые "прилетят" на свои места в момент при открытии страницы. Добавьте текстовый блок, но перед тем как применять к нему какое-либо форматирование, создайте стиль (Меню Object - Edit Style - Create Empty). Дайте стилю понятное имя и определите его в приложении (Application) - тогда он будет доступен на всех страницах (рис. 20.9).
Окно конструктора теперь находится в режиме редактирования стиля - показан только активный элемент. Две кнопки вверху позволяют переключаться из режима редактирования страницы в режим редактирования стиля (рис. 20.10).
Рис. 20.10. Переключение режима редактирования страницы и стиля Установите крупный (порядка 40pt) размер шрифта, полужирное начертание и какуюнибудь контрастирующую с фоном главной страницы заливку. Добавьте тень: нажмите на вкладке Appearance панели Properties кнопку New напротив слова Effect и в появившемся окне выберите DropShadowEffect. После этого выйдите из редактирования стиля. Добавьте ещё 2-3 текстовых блока с произвольным текстом и примените к ним созданный стиль. Для этого каждый блок сначала следует выделить, а затем выбрать стиль через меню Object - Edit Style - Apply Resource. Разместите объекты на странице произвольным образом (для перемещения используйте инструмент Selection с панели инструментов) - например, так, как показано на рис. 20.11.
Рис. 20.11. Текстовые блоки с применённым стилем Теперь, если изменить стиль, изменятся и все элементы, к которым он применён.
3. Проверка: запуск приложения в браузере Перед тем как перейти к более сложной части работы, следует убедиться, что на данном этапе всё работает правильно. Вернитесь на страницу MainPage, выделите фрейм, и среди его свойств на вкладке Common Properties задайте Source, выбрав из выпадающего списка имя страницы AnimatePosition.xaml. Запустите проект (меню Project - Run или F5). При этом все файлы проекта автоматически сохранятся, произойдёт компиляция, создастся xap-архив с Silverlightприложением и тестовая страница TestPage.html, которая содержит HTML-элемент object, ссылающийся на xap-архив. Страница TestPage.html будет открыта в браузере, и вы должны увидеть главную страницу с заголовком и фреймом, в котором расположены созданные вами в данной части работы текстовый блоки. В адресной строке браузера находится адрес такого вида: http://localhost:1874/TestPage.html#/AnimatePosition.xaml Во-первых, следует отметить, что был запущен веб-сервер Microsoft Expression Development Server - это позволяет тестировать приложения в условиях, приближенных к реальным. Хотя данное приложение вполне будет запускаться и путём простого открытия тестовой страницы из файловой системы в любом браузере. Также интересен тот факт, что адрес включает имя страницы в навигационном фрейме. Когда страниц станет несколько, можно будет делать переходы между ними, модифицируя соответствующую адресную часть (и создавая гиперссылки извне с указанием конкретной внутренней страницы).
Часть 3. Создание анимации перемещений объектов 1. Создание элемента StoryBoard Нажмите кнопку "+" на панели Objects and Timeline (в которой находится дерево объектов). В появившемся окне дайте создаваемому элементу понятное имя, например, sbAppearance (рис. 20.12).
Рис. 20.12. Кнопка для добавления объекта StoryBoard Рядом с деревом объектов появилась временная шкала анимации, а в окне конструктора появилась надпись "sbAppearance timeline recording is on", т.е. происходит запись StoryBoard. Когда запись включена, все манипуляции в окне конструктора и на панели свойств приобретают другой смысл: статические (исходные) состояния объектов не изменяются - вместо этого происходит фиксация изменения свойств с привязкой к моменту времени, указываемому курсором. Если требуется изменить начальные состояния, выключите запись (красная круглая кнопка рядом с надписью).
2. Запись анимации В этом примере эффект пусть будет, например, таким: при загрузке страницы текстовые блоки поочерёдно "вылетают" с разных сторон и, слегка пружиня, останавливаются на своих местах. Для его реализации нужно всего лишь отметить на временной шкале, в какой момент времени каждый объект должен быть в том или ином месте и уточнить функцию интерполяции, которая по умолчанию линейная. Установите курсор временной шкалы на момент, когда анимация должна закончиться (например, полторы секунды), выделите текстовые блоки в дереве объектов и нажмите кнопку "Record Keyframe" (записать ключевой кадр). На шкале появятся отметки напротив имени каждого из блоков, символизируя записанные кадры (рис. 20.13).
Рис. 20.13. Отображение записанных кадров на временной шкале На самом деле, ещё ничего не записано, поскольку не ясно, что будет меняться в анимации. Переместите курсор на начало временной шкалы и задайте начальное состояние анимации: блоки разнесите в разные стороны за пределы страницы (пользуясь инструментом Selection), а на вкладке Appearance панели свойств обнулите непрозрачность (Opacity). Просмотрите анимацию в действии, нажав кнопку Play на временной шкале. Линейную функцию перемещения между двумя указанными позициями можно модифицировать. Выберите маркеры, соответствующие окончанию анимации, на временной шкале (обведите их нажатой клавишей мыши, удерживая Ctrl). На панели свойств выберите функцию замедления анимации (Easing Function). Функции в группе In влияют на начало анимации; Out - на окончание; InOut - на то и другое. Функция Bounce даёт эффект пружины, который можно несколько ослабить увеличением параметра Bounciness (рис. рис. 20.14).
Рис. 20.14. Выбор и настройка функции замедления анимации Добьёмся теперь поочерёдного "вылета" блоков. Пусть, например, "вылет" каждого блока длится полсекунды - для этого следует изменить позиции маркеров на временной шкале. Маркеры окончания достаточно просто переместить мышью: первый на 0.5 сек от начала, а второй - на 1 сек. Маркеры начала тоже можно переместить, но тогда поведение объектов начиная от нулевой отметки будет определяться их исходным, статическим состоянием. Поэтому вместо этого создадим новые маркеры (ключевые
кадры) следующим образом: выделите блок, который "вылетает" вторым, установите курсор на 0.5 сек (время его "вылета") - при этом в конструкторе будет отображено интерполированное состояние его позиции и непрозрачности - и верните блок на место (траектория движения его центра показана в конструкторе тонкой точечной линией), а также сделайте его прозрачным. Аналогично поступите и с последним блоком (или блоками - если общее количество больше трёх). Проверьте анимацию в действии, нажав кнопку Play.
3. Запуск анимации. Если сейчас скомпилировать проект и открыть тестовую страницу в браузере, никакой анимации не произойдёт: не указано, когда её запускать. Важно понимать, что анимаций (которые моделируются при помощи элементов StoryBoard) может быть много (даже с участием одних и тех же объектов), и для запуска каждой из них нужен какойлибо источник. Если не прибегать к написанию кода, то в качестве источника можно использовать поведение (Behaviour) ControlStoryboardAction. Найдите его на вкладке Behaviours панели Assets и перетащите мышью на элемент Page (рис. 20.15).
Рис. 20.15. Добавление объекта ControlStoryboardAction Тем самым вы назначили элементу поведение, смысл которого - контроль над некоторым элементом StoryBoard. Поскольку анимация должна запускаться при загрузке страницы, в качестве элемента-источника события выбрана страница. На панели свойств следует указать, какое именно событие, как, и на какой StoryBoard будет влиять (рис. 20.16).
Рис. 20.16. Настройка объекта ControlStoryboardAction В данном случае событие страницы Loaded (загружена) будет вызывать действие Play элемента StoryBoard по имени sbAppearance. Теперь запустите проект и убедитесь в его правильной работе.
21. Лекция: Перспективы и расширения HTML Новые возможности в проектах спецификаций HTML 5 и CSS 3 Содержание • • • • •
Определение типа документа HTML 5 Улучшения, касающиеся форм Canvas Хранилище DOM CSS 3
o o
Новые селекторы Новые псевдоклассы
§ § o o •
Псевдокласс n-го потомка Новый обобщённый комбинатор соседства (~)
Программный интерфейс (API) селекторов Рамки и цвета
Вопросы
Последний стандарт HTML появился в 1998 году. После этого работа консорциума WWW над развитием HTML была на долгое время прервана, но в 2007 году возобновлена. В настоящее время работа над проектом HTML 5 ведётся W3C совместно с группой разработчиков, называемой Web Hypertext Application Technology Working Group (WHATWG). В основе этой работы лежит стремление создать спецификацию новой версии HTML, учитывающую реальные современные потребности веб-разработчиков и более точно (по сравнению с HTML 4) описывающую порядок интерпретации документа браузером. Момент, когда можно будет забыть HTML 4 и полностью перейти на HTML 5, наступит точно не скоро. Для этого спецификация HTML 5 сначала должна быть завершена, одобрена производителями браузеров и полностью реализована в браузерах. И ещё должно будет пройти какое-то время, чтобы доля старых браузеров, не поддерживающих новой спецификации, сократилась бы до пренебрежимо малой величины. Однако почему бы уже сейчас не создавать страницы, которые несколько красивее выглядят в браузерах, поддерживающих новые возможности HTML 5 и CSS 3? Главное, предусмотреть также поведение страниц в остальных сегодняшних (и, желательно, завтрашних) браузерах. В этой лекции рассматриваются далеко не все возможности, заложенные в новые спецификации (для этого нужен отдельный курс), а только отдельные интересные моменты, которые уже сейчас работают в тех или иных браузерах. Мы не будем уточнять, в каких именно, потому что ситуация меняется очень быстро. Эту информацию можно всегда уточнить в таблицах совместимости браузеров со стандартами например, http://www.quirksmode.org/dom/html5.html иhttp://www.quirksmode.org/css/c ontents.html .
Определение типа документа HTML 5 ОТД в HTML 5 упрощено до предела:
Современные браузеры воспринимают такое ОТД независимо от наличия у них поддержки HTML 5 (полной поддержки пока нет ни в одном браузере) - при этом они переходят в стандартный режим.
Улучшения, касающиеся форм Это, в первую очередь, валидация введённых пользователем данных и новые типы элемента ввода, созданные специально для ввода и валидации таких данных как email, URL, телефон, дата, время, число и т.п. В использовании всё очень просто: HTML-элемент input может иметь дополнительные значения атрибута type, datetimelocal, date, month, week, time, number,range, email и url. Браузер отображает элементы этих типов на экране специфическим образом. Также тип элемента ввода влияет на представление значения в DOM и способ его проверки перед отправкой формы.
Рис. 21.1. Новые элементы ввода в HTML 5 Браузеры, не понимающие новых типов input, отобразят их как . Таким образом, функциональность не страдает, и никаких усилий для соблюдения обратной совместимости прилагать не нужно. Однако, если вы хотите, чтобы, например, календарь отобразился в любом случае, то в качестве решения можно использовать одну из Javascript-библиотек. А можно поступить и так: сначала проверить, поддерживает ли браузер требуемый тип input и, если нет, то создать календарь на Javascript. <script type="text/javascript">
//создадим в памяти элемент input var inp = document.createElement("input"); //попытаемся установить его тип в "date" inp.setAttribute("type", "date"); //если тип остался обычным текстом, if (inp.type == "text") { //то используем JQuiry UI для создания календаря $("#calendar").datepicker(); } С проверкой вводимых пользователем данных в HTML 5 связан ещё целый ряд интересных моментов. Во-первых, поля обязательные для заполнения могут быть снабжены атрибутом required: Это гарантирует, что форма не будет отправлена с незаполненным полем. Другой интересный атрибут элемента input - pattern. С помощью атрибута pattern можно задать регулярное выражение, которому должен соответствовать введённый текст: В данном случае введённый текст должен состоять из цифр в количестве от 13 до 16. Пользуясь селекторами атрибутов CSS 3, можно связать элементов input с разным форматированием, например, так:
различные
состояния
<style type="text/css"> input:valid { background: lime; } input:invalid { background: red; color: white; } input:required { background: yellow; color: Red; } Результат показан на скриншоте и, видимо, не нуждается в пояснениях.
Рис. 21.2. Применение стилей к псевдоклассам, соответствующим состояниям элементов формы Упражнение. Создайте HTML-документ с формой и несколькими элементами ввода нового типа. Просмотрите документ сначала в браузере, поддерживающем эти типы элементов, затем - в не поддерживающем. Добавьте скрипт, сообщающий пользователю о том, полноценно ли отображается форма. Что касается новых средств валидации, то их применение пока сильно ограничено: если браузер их не поддерживает, то никакой валидации просто не будет. Как правило, это недопустимо (хотя на сервере в любом случае необходима ещё одна проверка принятых от клиента данных). Ссылки: http://www.whatwg.org/specs/web-forms/current-work/#extensions http://diveintohtml5.org/forms.html Пример работающей формы: http://devfiles.myopera.com/articles/67/example.html
Canvas Этот новый HTML-элемент предоставляет API для рисования. В отличие от SVG, Canvas оперирует не объектами (текст, линия, кривая), а точками, т.е. выполнение, например, команды fillRect создаст на холсте нарисованный прямоугольник, но не предоставит нового объекта, аналогичного rect в SVG, которым можно было бы манипулировать при помощи набора свойств и методов DOM, и который мог бы реагировать на внешние события. Зато работа Canvas с точечной графикой более эффективна, чем в SVG. Несколько команд рисования показано в примере 21.1. Canvas 2D <style type="text/css"> div { position: absolute; top: 50%; left: 50%; width: 600px; height: 400px; margin: -200px 0 0 -300px; } <script type="text/javascript"> window.onload = function() { /*получаем ссылку на холст*/ var canvas = document.getElementById('myCanvas'); /*контекст*/ var context = canvas.getContext('2d'); /*создаём градиент*/ var myGradient = context.createLinearGradient(0, 0, 600, 400); /*добавляем цветовые позиции к градиенту*/ myGradient.addColorStop(0, "green"); myGradient.addColorStop(1, "white"); /*устанавливаем созданный градиент как стиль заливки*/ context.fillStyle = myGradient; /*заливаем прямоугольную область*/ context.fillRect(0, 0, 600, 400); /*определяем стиль текста*/ context.font = "bold 50px sans-serif"; /*цвет обводки*/ context.strokeStyle = 'black'; /*толщина линий*/ context.lineWidth = '3.0'; /*цвет заливки*/ context.fillStyle = 'yellow'; /*выравнивание текста*/ context.textAlign = "center"; context.textBaseline = "middle"; /*рисуем обводку текста*/ context.strokeText('Hello, World!', 300, 200); /*рисуем заливку текста*/ context.fillText('Hello, World!', 300, 200);
Листинг 21.1. Рисование при помощи Canvas (html, txt)
В настоящее время элемент Canvas поддерживается большинством популярных браузеров, за исключением IE. Однако, IE поддерживает язык разметки векторной графики VML, который позволяет частично эмулировать Canvas, и для эмуляции создана Javascript-библиотека ExplorerCanvas (см. пример 21.1 - в нём к HTML-странице подключается скрипт excanvas.js). Таким образом, этот элемент с некоторыми ограничениями использовать можно. Ссылка на спецификацию: http://www.w3.org/TR/html5/the-canvas-element.html
Хранилище DOM Ещё один полезный механизм, заложенный в проект спецификации HTML 5 и уже реализованный в IE8, а также в ряде других браузеров - хранилище DOM. С помощью хранилища DOM, как и с помощью файлов Cookie, веб-разработчики могут сохранять данные на стороне клиента для конкретного сеанса (sessionStorage) или специфические данные домена (localStorage) в виде пар имя-значение. Хранилище DOM может предоставить значительно больше дискового пространства, чем файлы Cookie. В Internet Explorer в файлах Cookie можно сохранить только 4 КБ данных. В хранилище DOM в IE8 предоставляется приблизительно 10 МБ для каждой области хранения (в других браузерах - несколько меньше). С функциональной точки зрения хранилища DOM значительно отличаются от файлов Cookie. Из хранилища DOM значения не передаются на сервер с каждым запросом, как в файлах Cookie, и срок действия данных в локальной области хранения никогда не истекает. В отличие от файлов Cookie в хранилище DOM проще осуществлять доступ к отдельным фрагментам данных с использованием стандартного интерфейса, который приобретает все более широкую поддержку у поставщиков браузеров. Пример 14.2 иллюстрирует основные приёмы работы с хранилищем. Сохранение сеанса <script type="text/javascript"> var list; window.onload = function() { //сохраняем ссылку на список (она будет использоваться часто) list = document.getElementById('list'); var StorageSupported = false; //определяем, поддерживается ли хранилище: //некоторые браузеры создают исключение при обращении к sessionStorage -
//поэтому помещаем проверку в блок try/catch try { if (sessionStorage) StorageSupported = true; } catch (e) { }
if (StorageSupported) { //поддержка есть - сообщим об этом document.getElementById('msg').innerHTML = 'Ваш браузер ' + 'поддерживает'.fontcolor('green') + сеанса'; //проходим в цикле по всем элементам, уже сохранённым (если есть) for (var n = 0; n < sessionStorage.length; n++) { var key = sessionStorage.key(n); //помещаем их ключи и значения в список list list.options[list.options.length] = new Option(key sessionStorage[key], key); } } else { //поддержки нет - также сообщаем об этом document.getElementById('msg').innerHTML = 'Ваш браузер ' + 'не поддерживает'.fontcolor('red') + сеанса'; //получаем ссылку на массив элементов формы var formElems = document.forms[0].elements; //и делаем их недоступными (disabled) for (i = 0; i < formElems.length; i++) { formElems[i].disabled = 'disabled'; } } }
' хранилище в хранилище
+
':
'
+
' хранилище
//это событие возникает (если браузер его поддерживает) при изменении в хранилище document.onstorage = function() { //опустошаем список while (list.hasChildNodes()) { list.removeChild(list.firstChild); } //и воссоздаём его на основе изменившегося хранилища for (var n = 0; n < sessionStorage.length; n++) { var key = sessionStorage.key(n); list.options[list.options.length] = new Option(key sessionStorage[key], key); } }
+
':
'
+
Страница 1
Листинг 21.2. Сохранение сеанса при помощи механизма sessionStorage (html, txt)
Упражнения. Введите произвольный текст в области ввода. При необходимости нажмите кнопку "Обновить список" (браузер IE8 обрабатывает событие onstorage, остальные - пока нет). Список отображает введённые блоки текста, сохранённые в хранилище сеанса. Перейдите на страницу 2: а) в той же вкладке; б) в новой вкладке: в) начав новый сеанс (если используется IE8). Проследите в каждом случае: 1) отображаются ли в списке блоки, сохранённые на странице 1; 2) изменится ли список на странице 1, если его изменить на странице 2 (в случае "а" должен). Откройте код страницы 1 в редакторе и измените везде sessionStorage на localStorage. Запустите изменённую страницу и убедитесь, что данные в локальном хранилище доступны даже после перезапуска браузера. Пользоваться рассматриваемой технологией следует с осторожностью, поскольку лишь последние версии популярных браузеров её поддерживают. Поэтому на хранилище DOM следует возлагать задачи, связанные с повышением удобства пользователя (например, запоминание состояния страницы), но не с принципиальными моментами, касающимися функционирования приложения. Ссылки: http://dev.w3.org/html5/webstorage http://msdn.microsoft.com/ru-ru/library/cc197062(VS.85).aspx
CSS 3 В данном разделе рассматриваются те из многочисленных нововведений CSS 3, которые уже нашли поддержку в отдельных браузерах и представляют интерес для веб-дизайнера, не создавая при этом серьёзных проблем обратной совместимости. О поддержке конкретным браузером того или иного механизме можно узнать на http://www.quirksmode.org/css/contents.html.
Новые селекторы Теперь правила CSS могут назначать стили элементам по более сложным критериям, чем в CSS 2.1. Дополнения к селекторам атрибутов: новые операторы сравнения ^=, $= и *= находят элементы, свойства которых соответственно начинаются, заканчиваются или содержат в себе указанную строку. Этот механизм можно использовать, например, когда элементы формы или таблицы имеют осмысленные идентификаторы (idили name), состоящие из частей, которым можно поставить в соответствие некоторое форматирование. В примере 21.3идентификатор ячейки таблицы указывает, какие цвета применять для содержащегося в ней текста. table { font-family: Verdana; font-size: 40px; border-collapse: collapse; } td { border: 1px solid black; padding: 4px; text-align: center; } td[id^=r]:first-letter, td[id$=r] { color: Red; } td[id^=g]:first-letter, td[id$=g] { color: Green; } td[id^=b]:first-letter, td[id$=b] { color: Blue; } td[id^=v]:first-letter, td[id$=v] { color: Fuchsia; } td[id^=k]:first-letter, td[id$=k] { color: Black; } ...
Пример 21.3. Применение селекторов атрибутов CSS 3 (html, txt)
Рис. 21.3. Дополнительные селекторы атрибутов в CSS 3 Упражнение. Модифицируйте идентификаторы ячеек и создайте правила CSS, благодаря которым можно было бы назначать ячейкам ещё и фон (несколько градаций серого). Ссылка: http://www.w3.org/TR/css3-selectors/#attribute-substrings .
Новые псевдоклассы Псевдокласс n-го потомка Достаточно мощный механизм, позволяющий дифференцировать потомков по номеру следования, в том числе циклически. Простейший и востребованный пример чередование форматирования в абзацах или строках таблицы.
Рис. 21.4. Применение селектора n-го потомка В спецификации (см. http://www.w3.org/TR/css3-selectors/#nth-child-pseudo ) приводятся и более сложные примеры: p:nth-child(4n+1) p:nth-child(4n+2) p:nth-child(4n+3) p:nth-child(4n+4)
{ { { {
color: color: color: color:
navy; } green; } maroon; } purple; }
Очевидно, данные правила форматирования будут группировать элементы не парами, а четвёрками. Псевдоклассы, близкие по смыслу - :nth-last-child, :nth-of-type(), :nth-lastof-type(), :first-of-type, :last-of-type, :only-child, :only-of-type, :empty, где last означает отсчёт с конца, а of-type - счёт только элементов указанного типа, например: img:nth-of-type(2n) { float: left; }. Другие псевдоклассы: :target выбирает элемент, если переход по гиперссылке был сделан на него. Например, при переходе по ссылке http://example.com/html/top.html#section_2элемент с id=section_2 будет соответствовать селектору :target. :checked выбирает пользователем.
:not(X) формулирует отрицание к простому CSS-селектору. Новый обобщённый комбинатор соседства (~) При его помощи можно выразить следующее отношение: элемент со свойствами, определяемыми селектором, где-то перед которым в ряду соседей находится элемент со свойствами, определяемыми другим селектором. Приведём пример с простыми селекторами: абзацы после заголовков различного уровня будут иметь различное форматирование (при условии, что они являются соседями заголовков, а не вложены в какой-либо дополнительный контейнер). h1 ~ p { color: Red; font-size: 1.2em; } h2 ~ p { font-size: 1em; color: blue; } h3 ~ p { color: green; }
Рис. 21.5. Применение обобщённого комбинатора соседства Ссылка: http://www.w3.org/TR/css3-selectors/#general-sibling-combinators
Программный интерфейс (API) селекторов Селекторы предоставляют средства выборки элементов документа по разнообразным критериям - в первую очередь, для применения к ним стилей. Браузер, выполняя CSSправило, эту выборку осуществляет, и формирует результат - список элементов. Новые спецификации позволяют использовать результирующий список в пользовательских сценариях (раньше для этого приходилось довольствоваться тремя методами getElementById(), getElementsByName(), getElementsByTagName() и циклическим перебором элементов). Для этого в спецификации (см. http://www.w3.org/TR/selectors-api/ ) предусмотрены методы querySelector() иquerySelectorAll(), принимающие в качестве аргумента строки-селекторы (такие же, как в объявлениях стилей) и возвращающие либо первый элемент, соответствующий строке-селектору (первый метод) либо список всех соответствующих элементов (второй метод). Листинг 21.4. Применение метода querySelectorAll() (html, txt)
Рис. 21.6. Применение API селекторов
Рамки и цвета Наконец-то в CSS 3 можно задавать цветовой градиент. Согласно черновику спецификации, определение градиента для цвета заливки будет выглядеть, например, так: background: linear-gradient(-45deg, yellow, blue); background: radial-gradient(red, yellow, green); Идея в том, что фоном служит изображение, генерируемое браузером и задаваемое при помощи функций linear-gradient и radial-gradient. Данные функции предусматривают множество вариантов задания цветов, их позиций и направления градиента. В настоящее время браузеры ещё не реализовали в полной мере стандартных функций градиента, но уже появились экспериментальные альтернативы. Имена альтернативных реализаций функций включают префикс, указывающий на браузер (либо ядро браузера), в котором данная функций определена. Например, вы можете применять такие объявления:
Первое объявление воспринимается браузером Mozilla Firefox (и другими браузерами на ядре Gecko); второе - Apple Safari и Google Chrome (и другими, построенными на ядре Webkit); третье - остальными браузерами. Таким образом, какой-нибудь фон будет показан в любом случае, и внешний вид секции не пострадает.
Рис. 21.7. Определение градиентной заливки в CSS 3 Далее, градиент для рамки можно задать следующим образом: .border_color { border: 8px solid #888; -moz-border-bottom-colors: #555 #666 #777 #888 #999 #aaa #bbb #ccc; -moz-border-top-colors: #555 #666 #777 #888 #999 #aaa #bbb #ccc; -moz-border-left-colors: #555 #666 #777 #888 #999 #aaa #bbb #ccc; -moz-border-right-colors: #555 #666 #777 #888 #999 #aaa #bbb #ccc; } Здесь толщина границы - 8 пикселов, и для каждого ряда пикселов задан свой цвет - от более тёмного к более светло-серому. Браузеры, не воспринимающие свойств с префиксом -moz, проигнорируют их, и рамка останется просто серой, как указывает свойство border.
Рис. 21.8. Определение градиентной рамки в CSS 3 В CSS 3 скруглённые углы рамок можно создавать, не прибегая к дополнительным изображениям. Черновик спецификации определяет для этого свойство borderradius (см. http://www.w3.org/TR/css3-background/#the-border-radius). Экспериментальные свойства применяются на сегодняшний день так: .border_rounded {
Рис. 21.9. Создание рамок со скруглёнными углами в CSS 3 Спецификация предусматривает разное закругление всех углов, эллиптическую форму округлости и многие другие интересные вещи. Для рамок можно использовать и собственные изображения - для этого следует предоставить один файл и указать правила его деления на части с последующим повтором либо растяжением этих частей: .border_img { border: 8px solid #3FA9F5; -moz-border-image: url(border_img.png) 27 stretch; -webkit-border-image: url(border_img.png) 27 stretch; } Здесь указано, что файл следует разрезать с шагом в 27 пикселов (в обоих направлениях), и срединные участки растянуть (stretch) до требуемых размеров:
Рис. 21.10. Создание специальной рамки в CSS 3 путём растяжения фрагмента заданного изображения Вариант с повтором (а не растяжением) срединных фрагментов: .border_img { border: 8px solid #3FA9F5; -moz-border-image: url(border_img.png) 27 round; -webkit-border-image: url(border_img.png) 27 round;
Рис. 21.11. Создание специальной рамки в CSS 3 путём повторения фрагмента заданного изображения Исходное изображение:
И последний эксперимент с рамкой: она может отбрасывать тень: .box_shadow { -moz-box-shadow: 10px 10px 5px #888; -moz-background-clip:padding; -webkit-box-shadow: 10px 10px 5px #888; -webkit-background-clip:padding; }
Рис. 21.12. Создание тени для блока в CSS 3 Заодно в данном примере использовано ещё одно новое свойство: background-clip, которое может принимать значения border (заливка распространяется на область границы) или padding (не распространяется).
Ссылки: http://www.w3.org/TR/2002/WD-css3-border-20021107/#the-border-image-uri http://dev.w3.org/csswg/css3-images/ http://www.css3.info Рассмотренные в данном разделе примеры работают лишь в некоторых браузерах. Используя тот или иной приём, необходимо предусматривать и худший вариант - то, что принято называть "degrade gracefully", т.е., "отступление без потери лица". Если браузер не может отобразить градиентную заливку - должна быть определена простая заливка. Если невозможна фигурная рамка - должна быть простая рамка и т.д. Если используются новые селекторы и комбинаторы, то следует удостовериться, что и в тех браузерах, которые их игнорируют, страница всё равно выглядит приемлемо.
Вопросы 1. 2. 3. 4. 5. 6. 7.
Какие новые виды элементов формы предусмотрены в HTML 5? Какие имеются в HTML 5 возможности по проверке введённых в форму данных? В чём отличие технологий SVG и Canvas? Перечислите и охарактеризуйте дополнительные селекторы CSS 3. Какие новые методы выборки элементов документа введены в DOM? Какие новые свойства CSS 3 можно применять для работы с рамками и цветами? Какие дополнительные предосторожности следует принимать, пользуясь новыми средствами HTML и CSS?
22. Лабораторная работа: Знакомство с Silverlight (продолжение) Содержание • •
Часть 1. Создание цветовой анимации Часть 2. Создание интерактивных элементов
o o o o •
1. Рисование фигур и группировка объектов. 2. Создание первой анимации: эллипс. 3. Создание второй анимации: прямоугольник. 4. Создание третьей анимации: треугольник.
Часть 3. Создание гиперссылок
o o o
1. Создание цепочки гиперссылок на страницах 2. Создание отдельной страницы ссылок. 3. Редактирование HTML-страницы
Часть 1. Создание цветовой анимации Добавьте к приложению, созданному в предыдущей работе, ещё одну страницу (Page) с именем AnimateColor.xaml. Создайте несколько текстовых блоков и примените к ним стиль. Создайте StoryBoard с именем sbColor, установите курсор на 1 сек и измените цвета текстовых блоков. Теперь выделите StoryBoard, щёлкнув мышью по его имени (прямо под заголовком панели Objects and Timeline) и на панели свойств задайте вечный повтор с авто-реверсом (рис. 22.1).
Рис. 22.1. Настройка анимации на бесконечный повтор с авто-реверсом Запуск анимации задайте таким же образом, как и в предыдущем задании. Перед запуском приложения измените свойство Source навигационного фрейма на главной странице - укажите в нём страницу AnimateColor.xaml.
Часть 2. Создание интерактивных элементов
1. Рисование фигур и группировка объектов. Добавьте к приложению ещё одну страницу с именем Interactions.xaml. Изобразите на ней нечто подобное рис. 22.2
Рис. 22.2. Пример нескольких графических объектов, используемых для демонстрации интерактивной анимации Для рисования фигур используйте инструменты Прямоугольник и Эллипс, которые совмещаются на одной кнопке панели инструментов (рис. 22.3).
Рис. 22.3. Выбор инструментов Прямоугольник, Эллипс и Линия на панели К эллипсу применена радиальная градиентная заливка (рис. 22.4).
Рис. 22.4. Настройка радиальной градиентной заливки Прямоугольник залит сплошным цветом, а его рамка (Stroke) имеет относительно большую толщину (StrokeThickness), к которой применена градиентнаярадиальная заливка (рис. 22.5).
Рис. 22.5. Настройка толщины и градиентной заливки для рамки Треугольник можно нарисовать, например, пользуясь инструментом Pen - выбрав его, щёлкните мышью в трёх точках и, чтобы замкнуть фигуру, снова щёлкните в начальной точке. После этого к фигуре (Path) можно применять любую заливку. Нарисовав текстовые блоки, объедините их с соответствующими фигурами - это целесообразно сделать, поскольку анимация будет применена к каждой фигуре с надписью как к единому целому. Для этого: выделите фигуру и надпись (например, воспользовавшись инструментом Selection и обведя их мышью, либо щёлкнув по их названиям в дереве объектов, удерживая Ctrl) и примените команду меню Object Group into - Canvas. При этом в дереве объектов появятся элементы Canvas (холсты), которые сами по себе невидимы (если не применить к ним заливки), но выполняют группирующую функцию, как видно в дереве объектов (рис. 22.6).
Рис. 22.6. Сгруппированные объекты в дереве объектов Именно к холстам будет применена анимация.
2. Создание первой анимации: эллипс. Пусть эллипс с надписью (а точнее, группирующий их холст) при щелчке мыши увеличивается в размере, становясь прозрачным - как бы растворяется в странице. Создайте объект StoryBoard с именем sbDissolveEllipse, установите курсор на 1 сек и назначьте холсту два свойства: трёхкратное увеличение (рис. 22.7) и нулевую непрозрачность (Opacity).
Рис. 22.7. Установка масштабирования объекта Чтобы привязать запуск этой анимации к щелчку мыши по холсту, привяжите к нему поведение ControlStoryboardAction и настройте его свойства соответствующим образом. Проверьте анимацию в действии.
3. Создание второй анимации: прямоугольник. Прямоугольник пусть при подведении указателя дважды переворачивается. Для этого создайте объект StoryBoard с именем sbFlipRect, установите курсор на 0,5 сек и назначьте холсту поворот вокруг оси X порядка 360 градусов (рис. 22.8).
Рис. 22.8. Установка проекции (поворота холста) Привязав к холсту с прямоугольником поведение ControlStoryboardAction, в качестве события, инициирующего запуск анимации, выберите MouseEnter (вход указателя мыши в область объекта).
4. Создание третьей анимации: треугольник. Этот объект при нажатии клавиши мыши пусть улетает за пределы страницы, вращаясь, уменьшаясь и делаясь прозрачным. Сделайте эту анимацию самостоятельно.
Часть 3. Создание гиперссылок
1. Создание цепочки гиперссылок на страницах Перейдите на страницу AnimatePosition.xaml, закройте активный StoryBoard (чтобы случайно не записать что-либо) и перетащите на страницу элемент HyperlinkButton из группы Locations панели Assets. В свойствах гиперссылки укажите Content и NavigateUri (рис. 22.9р).
Рис. 22.9. Настройка свойств гиперссылки Теперь в работающем приложении можно переходить со страницы AnimatePosition.xaml на страницу AnimateColor.xaml, нажимая на гиперссылку. Аналогично свяжите и страницу AnimateColor с Interactions.
2. Создание отдельной страницы ссылок. Добавьте к приложению ещё одну страницу с именем Links.xaml и поставьте ссылку на неё на странице Interactions.xaml. Для размещения на странице Links двух наборов гиперссылок (внутренних и внешних) воспользуемся элементом управления TabControl. Найдите его в группе Locations на панели Assets, перетащите на страницу и расширьте (воспользовавшись инструментом Selection), как показано на рис. 22.10.
Рис. 22.10. Размещение элемента TabControl на странице Чтобы дать вкладкам заголовки, на панели свойств во вкладке Common Properties нажмите кнопку с многоточием напротив Items (Collection) и в открывшемся редакторе вкладок измените свойство Header у обоих элементов - один назовите "Внутренние", а второй - "Внешние" (рис. 22.11).
Рис. 22.11. Настройка свойств вкладок Кроме того, уберите белый фон элемента TabControl (рис. 22.12).
Рис. 22.12. Удаление фонового цвета Теперь разместите на вкладке "Внутренние" гиперссылки на все созданные в данной работе страницы, а на вкладке "Внешние" - 2-3 ссылки на внешние ресурсы. Для того, чтобы разместить какой-либо элемент во вкладке, следует сначала выделить вкладку в дереве объектов, а затем перетащить требуемый элемент (в данном случае гиперссылку) в окно конструктора (рис. 22.13).
Рис. 22.13. Добавление гиперссылки на вкладку Для внешних гиперссылок свойство NavigateUri следует задавать в полном виде (например, http://www.w3.org), не опуская названия протокола. Кроме того, для свойства TargetName введите значение _new (новое окно браузера), как показано на рис. 22.14.
Рис. 22.14. Настройка свойств гиперссылки
3. Редактирование HTML-страницы Найдите в папке с вашим Silverlight-приложением страницу TestPage.html (подкаталог Bin\Debug), создайте её копию и при помощи стилей центрируйте объект на странице.