Иллюстрированный самоучитель по созданию сайтов

1. Как создают веб-страницы
1.1 Как создают веб-страницы
1.2. Как разместить веб-страничку на сервере
1.3. Как написать веб-страницу
1.4. Обзор программ для просмотра веб-страниц
1.5. Обзор программ для создания веб-страниц
1.6.(Часть-I) Создание веб-страниц при помощи программы Allaire Homesite/Cold Fusion
1.6.(Часть-II)Автоматизация ввода
2. Основные средства языка htmL
 2.1. Простейшее форматирование текста
2.2. Самое главное на любой веб-странице — гиперссылки
2.3. Как создать списки на веб-странице
2.4. Создание таблиц
3. Графика на веб-странице
3.1.(Часть-I) Основные способы применения графики
3.1.(Часть-II)Изображение-карта
3.2. Графические форматы Интернета
3.3. Графические элементы оформления веб-страниц
3.4. Графические маркеры
3.5. Подготовка рисунков в программе Xara Webstyle
3.6.(Часть-I)Подготовка рисунков в программе Adobe Photoshop
3.6.(Часть-II)Украшение изображения мелкими деталями
4. Оформление веб-страницы с использованием стилей 4.1. Оформление с помощью атрибута STYLE
4.2. Определение стилей в специальной таблице
4.3. Обзор других возможностей стилевых таблиц
5. Использование звука на веб-странице
5.1. Добавление звукового оформления
5.2. Программы для сжатия звуковых фрагментов
5.3. Маленькие хитрости
6. Динамические веб-страницы на основе JavaScript 6.1. Простейшие примеры
6.2. Как писать собственные функции
6.3. Динамическое изменение внешнего вида страницы 6.4. Другие возможности языка JavaScript
7. Веб-страницы, реагирующие на действия пользователя
7.1. Ввод данных пользователем в формы htmL
7.2.(Часть-I)Страница, управляемая при помощи мыши
7.2.(Часть-II)Динамическое управление позиционированием элементов
7.3. Страница, управляемая с клавиатуры
7.4.(Часть-I)Динамическое отображение текста веб-страницы
7.4.(Часть-II)Использование других свойств при работе с текстом
7.5. Динамическое изменение графических элементов веб-страницы
8. Размещение элементов на веб-странице и навигация по сайту
8.1. Использование структуры фреймов
8.2. Управление расположением элементов веб-страницы с помощью таблиц
9. Дополнительные возможности формирования веб-страниц
9.1. Пример использования элемента управления Tabular Data
9.2. Пример простейшего серверного сценария


1

1. Как создают веб-страницы

1.1. От автора

Меня часто спрашивают: “Легко ли создавать веб-страницы и как это делается? ” При этом выясняется, что под словом создавать разные люди понимают самые различные вещи: и как придумать, что должно содержаться на веб-странице, и как написать ее код, как загрузить ее на сервер, как получить сетевое (доменное) имя, как вносить изменения и обновления и т. п.

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

При этом в самом написании кода веб-страницы нет ничего принципиально сложного, и мы постараемся это продемонстрировать в данной книге. Вы увидите, что, используя современные средства, можно не стеснять свою фантазию мыслями типа: “А можно ли запрограммировать то, что я задумал?” Правда, еще совсем недавно, года три тому назад, создатели веб-страниц имели весьма ограниченные возможности. Но компьютерные технологии развиваются очень быстрыми темпами. Вполне может случиться, что еще через три года возможности современных средств создания веб-страниц покажутся более чем скромными, однако для большинства задач их пока вполне достаточно, а иногда и с избытком.

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


1.2

1.2. Как разместить веб-страничку на сервере

Начнем с конца

Представим себе, что наша веб-страничка (или сайт) уже готова и мы с умилением любуемся ею на экране своего компьютера. Как же теперь сделать так, чтобы и другие посетители Интернета тоже могли ею любоваться?

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

Адрес в Интернете

Подобно тому как любой телефон в телефонной сети имеет свой уникальный номер, любой компьютер, подключенный к Интернету, тоже имеет свой уникальный номер, который называется IP-адресом. IP-адрес состоит из четырех чисел, разделенных точками (это, конечно, только для облегчения человеческого восприятия — на самом деле это всего лишь 32-битная последовательность), например: 195.34.32.11. Кстати, это реальный IP-адрес DNS-сервера московского Интернет-провайдера “МТУ-Информ”). По IP-адресу в Интернете можно найти любой компьютер.

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

Где найти сервер для публикации

Не все имеют постоянное соединение с Интернетом. Тем, у кого соединение временное, гораздо проще разместить свою веб-страничку на каком-нибудь чужом компьютере, специально для этого настроенном. Это может быть, например, сервер вашего Интернет-провайдера (как прабило, все провайдеры предоставляют такую услугу бесплатно) или один из так называемых бесплатных Интернет-серверов. На бесплатном Интернет-сервере можно получить некоторое количество дискового пространства для своей веб-странички. Таких серверов в Интернете множество. Вот лишь некоторые из них: сообщество Geocities (www. yahoo, corn), XOOM (xoom.corn/home), российский сервер “Халява” (www.halyava.ru), сервер www.chat.ru и многие другие.

Как отправить материалы серверу

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

Если вы собираетесь часто обновлять свою страницу, вам будет полезна служебная программа Ftpweb, написанная еще в 1996 г. компанией BIT Software (впоследствии переименованной в ABBYY). Эта программа может отслеживать, какие файлы странички были изменены с момента последней загрузки, и автоматически копировать их на сервер. От нас практически ничего при этом не требуется, кроме нажатия на кнопку Process (Исполнить). Программу до сих пор можно загрузить с сервера компании, хотя, к сожалению, новых ее версий не выпущено и, по всей види- мости, их выпуск не планируется.

Доменные имена

Хорошо, а как же будет “называться” наша страничка? Как пользователи Интернета смогут ее найти? Как мы уже говорили выше, любой компьютер в Интернете имеет свой уникальный IP-адрес. Поэтому, если страничка лежит на компьютере с IP-адресом, например, 194.34.45.8 в каталоге /Мураде, то любому пользователю для ее просмотра достаточно набрать в адресной строке броузера следующий адрес: http://194.34.45.8/Mypage. Однако запоминать и вводить адреса в цифровом виде не слишком удобно. Для облегчения задачи существует система так называемых доменных имен (DNS — Domain Name System). Большинству IP-адресов поставлено в соответствие некоторое название — доменное имя. Например, сайт Интернет-провайдера “Гласнет” находится по адресу http://www.glasnet.ru. Согласитесь, что запомнить и набрать такую запись человеку гораздо проще, чем бессмысленную комбинацию цифр.

Доменные имена выдаются в соответствии со строгими правилами. В конце имени, после последней точки, в них содержится так называемое имя домена верхнего уровня. В большинстве случаев это двухбуквенный код страны, которой принадлежит данный ресурс. Например, окончание .ru означает Россию, .иа — Украину, .de — Германию, .fr — Францию и т. д. Обширный список кодов стран вы можете найти в Приложении 6. Кроме того, доменом верхнего уровня может являться также трехбуквенный код, означающий организационную принадлежность ресурса. Например, .com — коммерческая организация, .gov — правительственная, .mil — военная и т. п.

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

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

Поясним сказанное на примере. Предположим, что имеется пользователь Сергей Сергеев, который зарегистрировался у провайдера Black Line, выбрав себе регистрационное имя (логин) sergesergeev. У провайдера, разумеется, есть собственный сервер и сайт с адресом www.blackline.ru. На этом сервере провайдер размещает веб-странички своих пользователей, каждую в отдельном каталоге. После того как Сергей Сергеев разместит свою веб-страничку на сервере провайдера, она будет, скорее всего, иметь адрес www.blackline.ru/~sergesergeev или просто www.blackline.ru/sergesergeev. Некоторые провайдеры вместо имени каталога позволяют использовать регистрационное имя в качестве домена третьего уровня, например, так: www.sergesergeev. blackline. ru.

Если же Сергей Сергеев решил разместить свою страничке на бесплатном сервере, например, в сообществе Geocities, то там ему выдадут какое-нибудь длинное имя, например: www.geocities.com/SiHconValley/6285. Сообщество Geocities — это виртуальный город со своими виртуальными улицами, кварталами и домами. Веб-страница клиента в этом “городе” — это как бы отдельное виртуальное домовладение. “Жители” этого “города” стараются селиться на тематических “улицах” по общим интересам, чтобы в свободное от основной работы время заходить друг к другу “в гости”. На самом деле, конечно. Silicon Valley (Кремниевая долина) — это просто каталог на жестком диске, и возможно, что и “домовладение” (то есть веб-страничка) с номером 6285 в нем уже реально существует.

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

Здесь и далее все имена и названия гипотетические. Например, провайдера Black Line у нас не существует. В тех случаях, когда используются реальные названия, это специально указано в тексте.

Логин (login, от log in) —имя для входа в систему.

Здесь и далее мы опускаем префикс http://, указывающий на соответствующий сетевой протокол, поскольку в большинстве программ просмотра веб-страниц протокол http определен по умолчанию и данный префикс добавляется к адресу автоматически.

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

Регистрация имен

А как быть, если хочется сделать адрес странички более коротким, запоминающимся? Для этого существуют многочисленные службы переадресации, например: come.to, www.da.ru, attend.to (все названия реальные). Например, если Сергей Сергеев разместил на своей страничке информацию о своей фирме “Филин”, он может бесплатно зарегистрировать такие имена, как filin.da.ru(или www.filin.da.ru), come.to/filin и т. п. При этом пользователь, набравший эти адреса в своем броузере, будет автоматически переадресовываться на веб-страничку, размещенную где угодно: на сервере провайдера, на сервере Geocities или еще где-нибудь.

Ну, а если вы хотите приобрести для себя домен второго уровня (например www.filin.ru), то вам придется обратиться в соответствующую организацию. Так, например, распределением имен в домене .ru занимается организация РосНИИРОС (www.ripn.ru). За регистрацию в этом случае придется заплатить деньги, однако в итоге вы будете иметь легко запоминающийся адрес. Кстати, многие пользователи, игнорируя услуги поисковых машин, часто пытаются найти веб-странички, набирая наугад адреса типа www.имя.Компания.ru, так что, имея такое имя, вы получаете большие шансы на посещение.

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


1.3

1.3. Как написать веб-страницу

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

Итак, начнем. В принципе, даже если написать простой текст в любом текстовом редакторе, то он уже может отображаться программой просмотра веб-стравиц. Например, воспользуйтесь программой Блокнот (Пуск > Программы > Стандартные > Блокнот) и напишите:

Домашняя страница Сергея Сергеева.

Сергей Сергеев - писатель юморист, автор 20 рассказов.

В жизни большой любитель собак и компьютерных игр.

Теперь сохраните этот файл с расширением имени .html .

Рис. 1.2. Простой текст, загруженный в броузер

Теги HTML

Пользователь увидит эту страничку так, как показано на рис. 1.2. Это уже что-то, хотя и не слишком привлекательно: во-первых, исчезло форматирование текста (абзацы), во-вторых, — как-то скучно смотрится. Кроме того, есть такие строгие броузеры, которые вообще не отобразят этот текст, если не увидят в нем подтверждение того, что он написан на языке HTML (языке гипертекстовой разметки, на котором и пишутся веб-страницы). Расширение .html такой броузер может посчитать недостаточным подтверждением, поэтому придется написать несколько дополнительных строк:

<HTML>

<BODY>

Домашняя страница Сергея Сергеева

Сергей Сергеев - писатель-юморист, автор 20 рассказов.

В жизни большой любитель собак и компьютерных игр.

</BODY>

</HTML>

Слова, заключенные в угловые скобки, являются служебными словами языка HTML. Их принято называть тегами (tags). Теги никогда не отображаются при просмотре страницы — они служат для управления оформлением.

Существуют разные транскрипции слова browser, означающего просто программу просмотра веб-странип. Некоторые пишут “броузер”, а другие — “браузер”. Мы будем придерживаться второго варианта.

Тег <HTML> , который вы видите в первой строке, означает, что наш текст действительно написан на языке HTML. Большинство тегов языка HTML — парные. Они обязательно требует присутствия закрывающего тега. Например, в этом примере в первой строке стоит открывающий тег <HTML> , а в последней — закрывающий тег </HTML>. Все, что расположено между ними, считается .HTML-документом.

В языке HTML совершенно не имеет значения, строчными или прописными буквами записаны теги. Можно написать </HTML> или <html> — для броузера это одно и то же. Однако принято писать теги HTML прописными буквами, чтобы они лучше выделялись на фоне основного текста.

В рассмотренном примере вы видите еще один тег — <BODY> . Все, что расположено между ним и его закрывающим тегом ( </BODY> ), считается “телом” документа и отображается на экране. HTML,-документы, помимо “тела”, обычно содержат еще и заголовок, в котором заключена различная служебная информация. Заголовок располагается между тегами <HEAD> и </HEAD> . Например, следующий код будет отображен в броузере так, как показано на рис. 1.3.

<HTML>

<HEAD>

<ТIТLЕ>Домашняя страница Сергея Сергеева </TITLE>

</HEAD>

<BODY>

Домашняя страница Сергея Сергеева.

Сергей Сергеев - писатель-юморист, автор 20 рассказов.

В жизни большой любитель собак и компьютерных игр.

</BODY>

</HTML>

Рис. 1.3. Простейшая страничка: текст и заголовок

Обратите внимание на то, что в заголовке окна броузера также появились слова “Домашняя страница Сергея Сергеева”. Это произошло потому, что в разделе заголовка <HEAD> мы поместили этот текст между тегами <TITLE> и </TITLE>

Теперь вспомним о том, что при отображении в броузере наш текст потерял форматирование. Это произошло потому, что броузер игнорирует перевод строки. Однако если вы все же хотите видеть свой текст с таким же разбиением на строки, какое было в редакторе Блокнот, нужно заключить его между тегами <PRE> и </PRE>:

<HTML>

<HEAD>

<ТIТLЕ>Домашняя страница Сергея Сергеева</ТIТLЕ>

</HEAD>

<BODY>

<PRE>

Домашняя страница Сергея Сергеева

Сергей Сергеев - писатель-юморист, автор 20 рассказов.

В жизни большой любитель собак и компьютерных игр.

</PRE>

</BODY>

</HTML>

Результат показан на рис. 1.4. Уже лучше, не правда ли? Однако есть два момента, из-за которых мы не советовали бы без крайней необходимости употреблять тег <PRE>. Во-первых, как видно из рисунка, текст теперь отображается так называемым моноширинным шрифтом, похожим на шрифт пишущей машинки. Большинство броузеров отображают текст,

Рис. 1.4. Страничка, отформатированная с помощью тега <PRE>

заключенный между тегами <PRE> и </PRE> , именно так. Во-вторых (и это главное), в том, что броузер игнорирует разбиение текста на строки, есть свой глубокий смысл. Например, написанная строка может не поместиться в окне просмотра, и тогда, если бы не было тега <PRE> , броузер автоматически перенес бы ее часть на следующую строку, чтобы пользователю было удобно читать весь текст. Тег <PRE> не позволяет этого сделать, и если строка “вылезет” за пределы окна просмотра, то для ее чтения придется воспользоваться горизонтальной полосой прокрутки, что неудобно и обычно раздражает. Другими словами, если вы используете тег <PRE> , вам придется специально заботиться о длине строк, а это затруднительно, поскольку никто заранее не знает, какой размер окна броузера будет у пользователя. Без тега <PRE> броузер позаботится об удобстве просмотра сам (это будет проиллюстрировано далее на рис. 1.6).

Для форматирования текста существует множество специальных тегов. Сейчас рассмотрим самый простой из них — тег <BR> . В том месте, где он стоит, происходит принудительный переход на новую строку. (Причем в исходной записи можно продолжать текст на этой же строке — это не имеет значения.) Тег <BR> не имеет закрывающего парного тега, он употребляется сам по себе. Вот как сохранить наше форматирование текста без использования тега <PRE>

<HTML>

<HEAD>

<ТIТLЕ>Домашняя страница Сергея Сергеева.</TITLE>

</HEAD>

<BODY>

Домашняя страница Сергея Сергеева.

<BR>

<BR>

Сергей Сергеев - писатель-юморист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.

</BODY>

</HTML>

Результат показан на рис. 1.5. Как видите, форматирование текста сохранено, шрифт остался пропорциональным и не превратился в моноширинный, а кроме того, если пользователь почему-либо будет просматривать страничку в очень узком окне, он все равно увидит весь текст (рис. 1.6).

И, наконец, еще одна деталь: иногда броузеры или другие программы обработки требуют, чтобы в начале HTML-документа обязательно стоял служебный тег <!DOCTYPE> , в атрибутах которого должна быть указана версия языка и некоторая другая информация. Так что в корректном виде наша страничка будет выглядеть вот так:

рuc. 1.5. Страничка с простейшим

Рис. 1.6. Та же страничка в форматированием текста узком окне броузера

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТIТLЕ>Домашняя страница Сергея Сергеева </TITLE>

</HEAD>

<BODY>

Домашняя страница Сергея Сергеева <BR><BR>

Сергей Сергеев - писатель-юморист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.

</BODY>

</HTML>

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


1.4

1.4. Обзор программ для просмотра веб-страниц

Различия между броузерами

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

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

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

Броузер Internet Explorer

На сегодняшний день наиболее популярной программой просмотра веб-страниц является броузер Microsoft Internet Explorer, которым пользуется примерно половина всех бродящих по Интернету. MS Internet Explorer версии 5 поддерживает большинство требований HTML 4.0, и именно на эту программу мы будем ориентироваться в примерах, приведенных в этой книге. Эта программа бесплатна, и ее можно загрузить с адреса http://www.microsoft.com/windows/ie_intl/ru/download/. Там же можно обновить версию броузера и взять различные дополнения к этой программе. Почти все кардинальные новшества появились в программе MS Internet Explorer начиная с версии 4. Однако некоторые моменты, связанные в основном с реакцией на пользовательские действия и интерпретацией кода, написанного на языке JavaScript, все же существенно изменились в пятой версии. Поэтому не удивляйтесь, если страничка, написанная для Internet Explorer версии 5, при просмотре в четвертой версии будет выдавать, например, сообщения об “ошибке сценария”. Кстати, пятая версия Internet Explorer способна автоматически корректировать мелкие неточности. Другие броузеры этого не умеют, и для них эти неточности будут выливаться и сообщения об ошибках. Программа Internet Explorer поддерживает в качестве сценарного языка не только язык JavaScript,но и изобретенный компанией Microsoft язык VBScript, который происходит от языка Visual Basic. Поскольку веб-страницы, написанные с использованием VBScript, реально существуют, то только использование броузера Internet Explorer позволяет сегодня адекватно отобразить их содержимое. В языке VBScript появились некоторые интересные возможности, отсутствовавшие в JavaScript 1.0, такие, например, как функция автоматического игнорирования ошибок в цикле (On Error Resume Next). Мы не рассматриваем в этой книге язык VBScript, поскольку все же универсальным языком сценариев на сегодняшний день является JavaScript.

Что касается более ранних версий MS Internet Explorer, то их использование порождает ряд проблем. Так, например, в третьей версии использована довольно своеобразная реализация JavaScript, и некоторые функции, написанные для более поздних версий или для броузеров компании Netscape, в Internet Explorer 3 работают не совсем правильно. Кроме того, поскольку проект HTML 4.0 тогда еще только зарождался, в Internet Explorer 3 отсутствуют функции реакции на пользовательские действия, возможность произвольного расположения элементов оформления и др. Нет также поддержки каскадных таблиц стилей. В некоторых случаях возникают проблемы с навигацией между фреймами. А в еще более ранних версиях этого броузера вообще отсутствовала поддержка языков сценариев и были доступны только самые простые средства.

Броузер Netscape Navigator

Вторым по популярности броузером в мире является Netscape Navigator. В отличие от MS Internet Explorer, эта программа реализована для многих платформ, включая OS/2 и UNIX с ее клонами. На “He-Win.dows-компью-терах” Netscape Navigator продолжает оставаться наиболее популярной программой просмотра веб-страниц.

На момент написания этих строк вышел второй предварительный релиз шестой версии Netscape Navigator В этой версии также реализована поддержка многих требований HTML 4.0, однако не в такой полной мере, как в MS Internet Explorer 5. В частности, на пользовательские действия по-прежнему могут реагировать далеко не все элементы веб-страницы. Программу Netscape Navigator можно бесплатно получить, обратившись по адресу www.netscape.com. В предыдущей версии этой программы (четвертой) не поддерживались новые теги, предложенные в четвертой версии Internet Explorer (например <BUTTON>), что очень затрудняло написание динамических страниц, совместимых одновременно и с Internet Explorer, и с Netscape Navigator. Третья и более ранние версии программы не поддерживали реакцию на пользовательские действия вообще, а также все теги, связанные с позиционированием.

Другие свойства просмотра

Несмотря на то что программами MS Internet Explorer и Netscape Navigator пользуется подавляющее большинство пользователей Интернета, существуют и другие броузеры, то и дело используемые в работе. Среди них стоит отметить программу Opera, которую можно получить по адресу www.operasoftware.com (однако эта программа не является бесплатной — она распространяется по принципу Shareware). Кстати, в 1999 г. эксперты отмечали, что поддержка каскадных таблиц стилей (CSS) лучше всего реализована именно в этой программе. Броузер Opera имеет много достоинств (компактность, скорость работы, удобный интерфейс с детальной индикацией загрузки страницы), и прочие. Однако поддержка динамических элементов здесь осуществлена еще в меньшей степени, чем в броузерах от Netscape.

Достоин внимания также и чисто российский броузер Ariadna. Он был спроектирован специально под нужды российских пользователей. К сожалению, после версии 1.3 разработчики прекратили работу над проектом.

Средства просмотра веб-страниц сейчас встраиваются также во многие программы более “общего” назначения, например в kfm (это файловый менеджер-просмотрщик KDE, StarOffice и даже в программу работы с электронной почтой The Bat! (для просмотра HТМL-вложений). Однако все они имеют ограниченные возможности по сравнению со специализированными программами, и при создании веб-страниц на них ориентироваться не следует.


1.5

1.5. Обзор программ для создания веб-страниц

Простейшие средства создания веб-страниц

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

Как уже говорилось выше, веб-страницы кодируются на языке гипертекстовой разметки — HTML. Вообще говоря, чтобы написать HTML-файл, достаточно иметь любой текстовый редактор, лишь бы он умел не добавлять в текст свои специальные символы. Самый простой вариант — это редактор Notepad (Блокнот), входящий в стандартную поставку Windows (рис. 1.7). Собственно говоря, это именно то, что нужно, — простейшая программа, сохраняющая написанный текст именно в том виде, в котором он был введен, и ничего лишнего. (Тем, кто не работает под Windows, в качестве замены Блокноту подойдет почти “все что угодно”: Edit — для MS-DOS, vi или jed — для Linux, Kedit — для Linux/KDE и т. д.)

Рис. 1.7. Код HTML в текстовом редакторе Блокнот

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

Веб-редактор TextPad

Итак, начнем. Тем, кто предпочитает набирать код HTML вручную, но кому не хватает функциональности Блокнота и подобных ему программ, можно посоветовать программу под названием TextPad, которую можно загрузить, обратившись по адресу www.textpad.com. Эта программа по сути весьма похожа на Блокнот, однако разработчики специально предусмотрели некоторые удобства для того, чтобы писать код HTML (а также языков Java, С, C++, Perl и еще некоторых). Это выражается в том, что при написании HTML -документа все теги автоматически подсвечиваются синим цветом, их атрибуты — темно-синим, а значения атрибутов — зеленым (цвета можно настроить по собственному желанию, так же, как и шрифт). Это очень удобно. К примеру, если автор случайно ошибется в имени тега или атрибута, то оно останется черным, и он сразу поймет, что здесь что-то не то. Правда, проверка не является “ интеллектуальной”: программа может спокойно “разрешить” приписать тегу какое-либо свойство, которого у него в принципе быть не может (спокойно подсвечивает абракадабру типа <BR ALIGN="top"> или </BR> ).

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

Веб-редактор TextPad позволяет автоматизировать набор многих тегов. Если не хочется набирать их вручную (многие этого не любят просто из-за того, что приходится переключаться на латинский шрифт), то обратите внимание на левую нижнюю часть окна программы. Там приведен список наиболее распространенных HTML-тегов, которые можно вставлять в свой основной текст двойным щелчком мыши. Правда, в списке указаны не сами теги, а их описание. Например, чтобы вставить тег <BR> , нужно выбрать из списка пункт Block > Break Line. Однако к этому быстро привыкаешь. Почти все пункты списка вставляют теги вместе с закрывающим парным тегом. Например, если выбрать пункт Block > Preformatted, в текст автоматически будут добавлены теги и <PRE> и </PRE> . Некоторые пункты добавляют сразу целые блоки-заготовки. Если, к примеру, выбрать пункт Table (Таблица), в текст будет вставлен такой код:

<TABLE ALIGN="left" BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="100%">

<TR ALIGN="left" VALIGN="middle">

<TH></TH>

<TH>?</TH>

<TR ALIGN="left" VALIGN=middle">

<TD> ? </TD>

<TD> ? </TD>

</TABLE>

Значения этих тегов и их атрибутов мы рассмотрим позже, а пока обратим внимание на то, что кроме списка тегов TextPad предоставляет нам также возможность выбирать из списка специальные символы (список HTML Characters), а также, если потребуется, любой управляющий символ, например символы псевдографики DOS и другие. Те, кто часто вводят какие-либо последовательности символов, что при написании веб-страниц не редкость, могут облегчить свою задачу, записав в TextPad соответствующие макросы. Для записи макроса надо нажать комбинацию клавиш CTRL+SHIFT+R (или выбрать из меню Macros пункт Record). При этом начнется запись макроса, то есть все последующие действия будут запомнены. Чтобы закончить запись, надо снова нажать комбинацию клавиш CTRL+SHIFT+R, после чего присвоить имя файлу макроса, а также дать название для представления макроса в меню. Здесь можно также дать, если нужно, краткое описание макроса и указать имя его автора. После нажатия на кнопку ОК название макроса появится в меню Macros. Выбрав его, можно ввести сразу всю заданную последовательность символов.

Для удобства отладки можно установить флажок в пункте Line Numbers (Нумерация строк) в меню View (Вид), — в этом случае все строки текста будут пронумерованы. Хочется отметить, что если в меню Configure (Настройка) включен пункт Word Wrap (Перенос по словам) для автоматического переноса концов длинных строк в видимую часть экрана, то каждая такая длинная строка все равно будет нумероваться одним номером, а не двумя или тремя (кстати, такая нумерация почему-то недоступна в замечательной программе Homesite, о которой речь пойдет ниже). А если в меню View (Вид) включить флажок Visible Spaces (Отображать пробелы), то можно увидеть на экране и “невидимые символы”, такие, как пробелы, символы табуляции и прочие.

В программе TextPad можно легко сравнить два файла, выбрав из меню Tools (Сервис) пункт Compare Files (Сравнить файлы). А если есть два (или более) похожих файла, в некоторые местах которых надо внести изменения, удобно использовать функцию Synchronize Scrolling (Одновременная прокрутка) из меню Configure (Настройка). В этом случае можно открыть сразу несколько файлов, например, выбрав из меню Windows (Окна) пункт Tile Vertically (Расположить по вертикали), и тогда при прокрутке одного из них другие прокручиваются синхронно. Среди других полезных функций программы TextPad стоит отметить возможность автоматической смены клавиатурного регистра командой Edit >

Change Case (Правка > Сменить регистр), автоматического копирования в буфер слова или строки, на которой находится курсор, с помощью команд Edit ” Cut Other (Правка > Вырезать) и Edit > Сору Other (Правка > Копировать), а также функцию проверки орфографии Tools > Spelling (Сервис > Правописание). И, конечно, здесь присутствует возможность просмотра созданного файла в броузере View > In Web Browser (Вид > В броузере).

Веб-редактор Arachnophilia

Завершив краткий обзор возможностей программы TextPad, давайте рассмотрим другую программу для написания .HTML-кода — Arachnophilia, которую можно получить по адресу www.arachnoid.com/arachnophilia.

Как и в предыдущем случае, программа автоматически подсвечивает синим цветом теги и атрибуты, а значения атрибутов — зеленым, что улучшает зрительное восприятие, хотя проверка правильности тегов и отсутствует. Зато если случайно забыть закрыть тег, то все последующее содержимое файла подсветится бордовым цветом, так что ошибка сразу бросится в глаза. В программе Arachnophilia предусмотрена автоматизация ввода тегов HTML. В нижней части окна имеются кнопки, каждая из которых открывает соответствующую кнопочную панель. На этих панелях расположены кнопки для быстрого ввода тегов. Например, если нажать кнопку Styles (Стили), то откроется панель управления, содержащая кнопки для ввода тегов форматирования текста . Нажатие на любую из них вводит тег или блок-заготовку. Например, после нажатия на кнопку BR в тексте появится тег <BR>, а после нажатия на кнопку HR — появится сразу целая заготовка: <HR WIDTH="95%" ALIGN=CENTER>.

Нажатие некоторых кнопок вызывает появление диалоговых окон. Например, нажав на кнопку Color (Цвет), можно открыть стандартное диалоговое окно выбора цвета, а с помощью кнопки TableWiz (Мастер таблиц) открывают диалоговое окно Table Wizard (Мастер таблиц), средствами которого можно предварительно задать количество строк и столбцов в таблице, а также определить ее ширину, цвет линий и некоторые другие параметры .

Отличительной особенностью программы является возможность легкого просмотра веб-страницы в различных броузерах, для чего в меню Preview (Предварительный просмотр) предусмотрен пункт Identify Browser (Указать Лроузер). Здесь можно назначить до шести различных броузеров, в каждом из которых легко открыть создаваемый HTML-файл для просмотра, даже не сохраняя его на диске.

Однако самым замечательным свойством программы, пожалуй, является функция Instant View (Немедленный просмотр), которая доступна в меню Preview (Предварительный просмотр). Если она включена и внутренний броузер, который также имеется в программе, открыт, то все изменения, вносимые в текст HTML, немедленно отображаются на экране! Правда, в некоторых случаях, программа не успевает за вводом данных и изображение в окне броузера может исчезать. Но не волнуйтесь, а введите следующий символ, и изображение снова появится.

В программе Arachnophilia существует множество дополнительных полезных функций. Например, в меню Selection (Фрагмент) есть команда Find/Replace/Count (Поиск/Замена/Пересчет), которая позволяет быстро найти или заменить нужные слова в выделенной области, что часто очень выручает при создании веб-страниц. Команда Tag Delimiters (Ограничители тегов) из того же меню позволяет преобразовать угловые скобки, являющиеся общепринятыми ограничителями тегов HTML, в специальные символы &lt и &gt, что необходимо, когда надо показать код HTML на самой веб-странице. Можно также осуществить обратное преобразование. В этом же меню есть команда Strip all HTML tags (Скрыть теги HTML), с помощью которой можно быстро освободить текст от HTML-тегов, например, для переноса его в другую программу. Программа Arachnophilia, кстати говоря, способна читать и записывать файлы формата RTF(Rich TextFormat). При открытии RTF-файла предлагается конвертировать его в формат HTML, но его можно редактировать и в обычном виде.

Интересно, что программу Arachnophilia 4.0 можно загрузить как в полном виде (это установочный файл размером полтора мегабайта), так и в сокращенном (1 Мбайт), если в системе установлены необходимые библиотеки. Можно также загрузить только исполняемый файл, а остальное дозагру-жать по мере необходимости.

Веб-редакторы типа WYSIWYG

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

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

Эффективно управлять оформлением страницы таким способом тоже не удается. Поэтому мы не будем долго задерживаться на веб-редакторах, работающих по прнципу WYSIWYG.

Вообще говоря, для редактирования HTML-текста в режиме WYSIWYG можно использовать даже такой текстовый процессор, как Microsoft Word. Начиная с версии MS Word 97 он позволяет набрать некоторый текст, отформатировать его и сохранить в формате HTML. Если будете это делать, не забудьте удалить комментарии...

Редактор Star Office

Более мощными средствами редактирования HTML-файлов располагает программа StarOffice. Здесь при открытии или создании HTML- файла соответственно меняется содержимое некоторых меню, что позволяет достаточно эффективно работать с HTML кодом. Самым приятным моментом здесь, пожалуй, является возможность установить флажок HTML Source (Исходный код HTML) в меню View (Вид), который отключает режим WYSIWYG и позволяет работать с исходным HTML-текстом, в котором все теги и их атрибуты подсвечены красным цветом. По своему усмотрению можно редактировать как исходный текст, так и отображаемый результат, переключаясь между режимами командой HTML Source (Исходный код HTML) из меню View (Вид). В отличие от других WYSIWYG-редакторов, StarOffice довольно корректно удаляет ненужные элементы при отмене пользователем каких-либо действий и не вставляет лишних комментариев. При этом он довольно активно использует каскадные таблицы стилей (CSS).

Перед подсветкой теги проверяются на корректность — ошибочно написанные теги красным цветом не выделяются. Однако надо иметь в виду, что программа не понимает новых тегов, таких, как <BUTTON> , <LABEL> и пр.

Netscape Composer

Еще одна WYSIWYG-ориентированная программа для редактирования .HTML-файлов встроена в броузер Netscape. Она называется Netscape Composer гораздо меньше, чем в предыдущей, однако, поскольку это модуль популярного броузера, ее тоже используют активно. Средства верхней инструментальной панели позволяют вставить в файл изображение (Image), горизонтальную линию (H.Line), таблицу, гиперссылку (Link) или якорь (Anchor). Ниже расположена небольшая панель для управления начертанием шрифта (полужирное, курсивное, подчеркнутое), а также его размером, отступом и выключкой. Здесь же можно выбрать цвет фона. С помощью выпадающих меню доступно еще несколько HTML-элементов.

Несмотря на доступность и популярность программы, мы вряд ли можем посоветовать использовать WYSIWYG-редакторы типа Netscape Composer для создания веб-страниц, за исключением каких-либо очень простых случаев. Если вам непременно хочется визуально отслеживать все вносимые изменения, то установите программу Arachnophilia и воспользуйтесь функцией Instant View.

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


1.6

1.6. Создание веб-страниц при помощи программы Allaire Homesite/Cold Fusion

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

Однако прежде всего необходимо отметить, что использование программы Homesite подразумевает знание пользователем языка HTML (а также, по желанию, JavaScript и др.) Программа автоматизирует ввод кода, проверяет ошибки и т. д., но она не в силах помочь, если пользователь не представляет себе, что такое HTML.

В этом разделе мы будем оперировать понятиями и тегами, значения которых поясняются в главах 2-8 этой книги. Поэтому, если вы сейчас еще не очень хорошо представляете, что означает тот или иной тег, не волнуйтесь — прочтите этот раздел бегло, а затем вернитесь к нему после прочтения всей книги (если, конечно, захотите использовать в своей работе программы Homesite/ColdFusion).

На момент написания этих строк последней версией программы Homesite является версия 4.5. На нее мы и будем ориентироваться в дальнейшем.

Итак, давайте начнем. Основное окно программы Homesite представлено на рис. 1.20. Как видите, оно разделено на две панели. Левая панель называется Resource Tab (Панель ресурсов) — она предназначена для различных вспомогательных функций. На правой панели (Панели редактирования) происходит собственно редактирование текста HTML.

Сначала давайте рассмотрим левую панель (Resource Tab). На ней располагаются шесть вкладок, обозначенных следующими значками (слева направо): Files (Файлы), Projects (Проекты), Site View (Схема сайта), Snippets (Отрывки), Help (Справка) и Tag Inspector (Средство просмотра тегов). Если почему-либо образы значков кажутся неочевидными, их можно заменить на текстовые обозначения командой Options > Settings > General > Tab Style (Параметры > Установки > Общие > Стиль ярлыков вкладок).

Работа с файлами

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

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

Обратите внимание на то, что помимо файлов, расположенных на локальном компьютере, средства вкладки Files (Файлы) позволяют также открывать и редактировать файлы, расположенные на удаленном сервере, используя доступ по протоколу FTP. Делается это следующим образом.

1. При установке программы Allaire Homesite 4.5 в системную папку /Мой компьютер автоматически добавляется элемент под названием Allaire FTP & RDS. В верхней части вкладки Files (Файлы) вместо имени диска можно выбрать этот элемент. При этом пункт Allaire FTP & RDS появится также в средней части вкладки.

2. Щелкните на этом пункте правой кнопкой мыши и выберите из контекстного меню пункт Add FTP Server (Добавить в сервер FTP). При этом откроется диалоговое окно Configure FTP Server (Настройка сервера FTP), в котором надо ввести следующие параметры удаленного сервера.

• Название сервера (любое — это делается для вашего удобства).

• Полный сетевой адрес без префикса ftp://. Например, для странички, расположенной в сообществе Geocities, это будет ftp. geocities. corn.

• Имя рабочего каталога. В большинстве случаев это просто символ “/”. При этом не забудьте установить флажок Relative from server-assigned directory (Относительно каталога, выделенного сервером). Без этого символ “/” будет означать не ваш пользовательский каталог, а корневую папку всего сервера, куда, как правило, запрещен доступ всем, кроме администратора сервера.

• Свое регистрационное имя и пароль для доступа на удаленный сервер.

• Полный http-адрec своей веб-странички (тот, который вы набираете в броузере для ее просмотра).

• Некоторые дополнительные данные.

3. После нажатия на кнопку ОК в средней части вкладки Files (Файлы) появится символ папки, расположенной на удаленном компьютере. Если соединение с Интернетом установлено, то ее можно открыть и оперировать с ее файлами практически так же, как и с файлами, находящимися на локальном компьютере.

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

Работа с проектами

Вторая слева вкладка панели Resource Tab называется Projects (Проекты). Она очень похожа по внешнему виду на предыдущую, но позволяет собрать файлы, физически размещенные в разных местах, в одну или несколько “виртуальных папок”. Гак можно обеспечить себе более удобный доступ к файлам, чтобы не искать каждый раз нужную папку на диске.

В верхней части вкладки можно быстро выбрать свой проект из раскрывающегося списка, точно так же, как на предыдущей вкладке мы выбирали диск. Рядом расположены три командные кнопки: Open Project (Открыть проект, New Project (Создать проект) и Deployment Wizard (Мастер доставки). Первые две кнопки в пояснениях не нуждаются, а с помощью третьей можно открыть Мастер доставки. С его помощью можно отправить веб-страницу на один или несколько серверов через локальную сеть или Интернет. Имеется даже возможность генерации сценария, который будет через определенные промежутки времени автоматически производить доставку обновленных версий вашей странички на удаленный сервер.

Схема сайта

Средства третьей вкладки — Site View (Схема сайта) — предназначены для просмотра схемы разрабатываемого веб-сайта. Связи между HTML- документами, рисунками и прочими объектами на схеме показаны пунктирными наглядно увидеть связи между элементами. Щелчок мыши на каком-либо элементе схемы приводит к выделению соответствующего элемента в окне редактирования.

Выделив какой либо элемент, являющийся HTML- документом, можно перейти к его редактированию на правой панели окна программы. Для того щелкните на данном элементе правой кнопкой мыши и выберите в контекстном меню команду Edit (Правка). Схему сайта можно просмотреть как в виде диаграммы, так и в виде обычного дерева каталогов. Для переключения с одного вида на другой, нужно щелкнуть правой кнопкой мыши и любом месте вкладки Site View (Схема сайта), выбрать в контекстном меню пункт View Style (Метод просмотра) и установить флажок либо Tree (Дерево), либо Chart (Диаграмма).

Прочие вкладки

Следующая вкладка. Snippets (Отрывки), предназначена для создания коротких шаблонных текстов для ваших веб-страниц, их каталогизации и быстрой вставки в документы.

Затем идет вкладка Help (Справка), которая, скорее всего, в комментариях не нуждается — это великолепный справочник по использованию программы Homesite, а также языку HTML и различным дополнительным программам, которые можно бесплатно получить в Интернете.

И, наконец, последняя вкладка — Tag Inspector (Средство просмотра тегов). Она позволяет просмотреть теги, имеющиеся в HTML-документе, в виде иерархической структуры. Выделив какой-либо тег в этом “дереве”, можно получить в нижней части вкладки полный список доступных атрибутов и событий этого тега. Список организован в виде таблицы, в которую можно добавить какие-либо значения. Все сделанные изменения тут же отображаются на панели редактирования документа (но не сразу в момент ввода, а после перехода на другое поле таблицы).

Такие возможности, вкратце, предоставляет панель Resource Tab. Кстати, с помощью клавиши F9 ее можно быстро убрать с экрана, если захочется развернуть панель редактирования во всю ширину окна программы. Вернуть панель Resource Tab на экран можно повторным нажатием клавиши F9.

Панель редактирования

Теперь давайте кратко рассмотрим основную часть окна программы — панель редактирования. Вкладки:

Edit (Правка), Browse (Просмотр) и Design (Оформление). На первой HTML- документ представлен в виде исходного текста. При этом происходит автоматическая подсветка тегов. Ссылки и якоря выделяются темно-зеленым цветом, графические теги — бордовым, остальные теги — темно-синим. Теги встроенных сценариев выделяются коричневым цветом, а встроенные функции и другие зарезервированные слова и элементы языка сценариев — полужирным начертанием. Различными цветами подсвечиваются также и стилевые блоки, что намного облегчает восприятие и позволяет “ на лету” устранять случайные ошибки. Все цвета можно изменить по желанию, выбрав в меню Options (Параметры) команду Settings (Настройки) и, далее, нажав кнопку Edit Scheme (Правка цветовой схемы) в окне Editor > Color Coding (Изменить > Цветовая маркировка).

При ручном вводе HTML-текста, происходит автоматическая проверка правильности введенных тегов (если этого не происходит, ее можно включить, установив флажок Options > Settings > Validation > Tag validation (Параметры > Настройки > Проверка > Проверка тегов). При вводе заключительного ограничителя тега (>) программа проверяет правильность тега. Если тег правильный, в строке состояния отображается запись Tag validated (Тег проверен). В противном случае строка состояния подсвечивается красным цветом и в сопровождении одного из системных звуков Windows в строке состояния появляется надпись, поясняющая, что такой тег не существует или его использование не рекомендовано в текущей версии HTML. Если эстетичность кода вас не очень заботит, то можно смело игнорировать сообщения о нерекомендованных тегах.

Однако совершенно не обязательно вводить теги вручную. Для облегчения работы можно использовать функцию Tag Insight (Построитель тегов). Если она выключена, включите ее установкой флажка Options > Settings > Editor > Tag Insight > Enable Tag Insight (Параметры > Настройки > Редактор > Построитель тегов > Задействовать построитель). В этом случае через две секунды

после ввода символа начала тега (время можно изменить в том же разделе настроек Options > Settings > Editor > Tag Insight) откроется раскрывающийся

список доступных тегов. Остается только выбрать нужный. Этот же механизм можно использовать при вводе функций сценариев JavaScript.

Кроме того, в программе предусмотрена возможность автоматически добавлять закрывающие теги при вводе первого из “парных” тегов. Обычно функция по умолчанию выключена, но ее можно включить с помощью флажка Options > Settings > Editor > Tag Completion (Параметры > Настройки > Редактор > Завершение тегов). В этом случае при вводе, например, тега BODY>, сразу вместе с ним автоматически вводится тег </BODY>. Можно также включить функцию Options > Settings > Editor > Auto Completion (Параметры > Настройки > Редактор > Автозавершение) для автоматического закрыта кавычек, комментариев HTML и пр.

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

dt4

и нажатии комбинации CTRL+J запись dt4 автоматически заменяется на:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

Аналогично, набрав

scriptj

и нажав комбинацию CTRL+J, можно получить следующий блок:

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

<!--

</SCRIPT>

Согласитесь, что автоподстановка экономит немало времени, особенно когда мы можем сами задать нужные “сокращения” для часто используемых фрагментов кода. Задание сокращений выполняют командой Options > Settings > Editor > Code Templates > Add (Параметры > Настройки > Редактор > Шаблоны кода > Добавить).

Большинство клавиатурных сокращений, знакомых пользователям по другим программам, например текстовым процессорам, в веб-редакторе Homesite дают ожидаемый результат. Например, традиционное применение к выделенному фрагменту полужирного начертания шрифта с помощью комбинации клавиш CTRL+B, или курсивного начертания комбинацией CTRL+I, а также подчеркивание текста комбинацией CTRL+U, здесь также работает. При этом выделенный фрагмент обрамляется соответствующими тегами.


Автоматизация ввода

Теперь давайте обратим внимание на панель инструментов для быстрого ввода тегов (Quick Bar), расположенную в правой верхней части окна программы. Элементы управления, представленные на этой панели, предназначены для автоматизации ввода элементов веб-страницы. Элементы управления сгруппированы в несколько вкладок:

• Common — для ввода тегов, которые используются наиболее часто;

• Fonts — для изменения параметров шрифта;

• Tables — для создания таблиц;

• Frames — для создания фреймовых структур;

• Lists — для создания списков;

• Forms — для ввода элементов форм;

• Script — для подготовки ко вводу сценариев, Java-апплетов и элементов ActiveX;

• CFML—для ввода тегов ColdFusion;

• ASP — для определения некоторых элементов динамических страниц active server pages;

• Linkbot — для автоматической проверки ссылок с помощью внешней программы Linkbot.

Если на панели QuickBar видны не все вкладки, щелкните на ней правой кнопкой мыши, и в открывшемся меню отметьте те вкладки, которые хотите сделать видимыми. Подробно разбирать все вкладки панели Quick Bar мы здесь не будем, но общий принцип работы с ними рассмотрим.

На каждой вкладке представлены командные кнопки, с помощью которых можно быстро ввести нужный тег или целый блок-заготовку. Например, если перед вами совершенно чистая страница, нажмите на самую левую кнопку вкладки Common — это кнопка Quick Start (Быстрый старт). Из открывшегося списка можно выбрать тип документа и быстро сгенерировать его .HTML-заголовок. А если нажать вторую кнопку той же вкладки — кнопку Body, то откроется диалоговое окно, в котором можно изменить свойства текущей страницы. Наглядно, с помощью раскрывающегося списка, организован выбор цвета текста и фона, а если ни один из предложенных цветов не подходит, командой Custom (Настроить) можно открыть полную палитру доступных цветов. В небольшом окне справа можно увидеть, как будет смотреться избранное цветовое сочетание.

Для выбора фонового рисунка служит кнопка, расположенная рядом с полем Background Image (Фоновый рисунок). Она открывает стандартное окно выбора файла с возможностью его предварительного просмотра. Конечно, можно ввести название графического файла и просто с клавиатуры.

Для ввода значения атрибута STYLE= также можно воспользоваться раскрывающей кнопкой соответствующего поля. При этом открывается окно внешней программы TopStyle. Это же окно будет открываться при каждой установке атрибута STYLE= для любого тега или при редактировании стилевого блока. В его правой части находится панель Инспектора стилей (Style Inspector), на которой в алфавитном порядке приведены все доступные свойства стилей. Обратите внимание на то, что набор доступных свойств можно изменять в соответствии со своими запросами. Это может быть полный набор из спецификации CSS уровня 1 или 2, или набор свойств, поддерживаемых различными версиями броузеров. Необходимый набор можно выбрать из раскрывающегося списка в Инспекторе стилей.

Значения доступных свойств стилей можно выбирать в Инспекторе с помощью раскрывающихся списков. Правда, некоторые значения, например цифровые значения параметров в соответствующих диалоговых окнах, лучше все-таки вводить вручную. Все изменения значений тут же отображаются в левой части окна TopStyle. По завершении настройки нажмите кнопку Done (Готово) — и соответствующий текст появится в поле ввода Style (Стиль). Теперь обратите внимание на еще одну особенность окна Body . На его нижней панели (там, где имеются поля Left Margin, Top Margin и Fixed Background) изображен значок броузера Internet Explorer 4. Наличие этого значка означает, что атрибуты, представленные в данном разделе, будут ( работать только в этом броузере.

К этому вопросу мы еще вернемся, а пока нажмите кнопку ОК, и вы увидите, что все установленные атрибуты тега <BODY> появились в тексте, например, вот так:

<BODY
TEXT="Blue" BACKGROUND="arrowl.gif"
BGCOLOR="Fuchsia" LINK="Aqua"
VLINK="Black" ALINK="Gray"
STYLE="background-position: right;

border-style: dotted; background-repeat: repeat-y;">

Диалоговые окна редактирования тегов

О том, что это все означает, мы поговорим в следующих главах, а пока что рассмотрим еще одно типичное диалоговое окно программы. Откройте вкладку Tables и нажмите кнопку Table dialog — обычно она вторая слева. Откроется диалоговое окно пелактопа тегов ТagEditor — TABLE

— Internet Explorer 3;

— Netscape Navigator 3;

—Internet Explorer 4;

— Netscape Communicator 4;

— броузер Opera (подразумевается версия 3.5).

Как правило, свойства, которые поддерживаются каким-либо типом броузера более низкой версии, поддерживаются и в его дальнейших версиях, то есть, если значок показывает, что тот или иной атрибут поддерживается в броузере Internet Explorer 3, то это означает, что он, скорее всего, будет поддерживаться также и в броузере Internet Explorer 4 или в пятой версии. Однако броузеры других типов, даже более старших версий, поддерживать этот атрибут, скорее всего, не будут.

Кроме того, в подобных диалоговых окнах имеется вкладка HTML 4.0, на которой можно устанавливать значения новых атрибутов, стандартизированных в четвертой версии языка HTML. Если какой-либо из этих “ новых ” атрибутов поддерживался и в более ранних версиях некоторых броузеров, то на этой вкладке вы увидите раздел Also in: (А также в...), в котором эти броузеры обозначены с помощью значков.

Дополнительно, данное диалоговое окно содержит еще три вкладки. Средства вкладки Style Sheets/Accessibility (Списки стилей) служат для установки значения атрибута STYLE= (с помощью внешней программы TopStyle, как уже говорилось выше) или для определения стилевого селектора (CLASS) и еще некоторых связанных с этим атрибутов. Средства вкладки Language (Язык) предназначены для установок, связанных с языком текста, и, наконец, средства вкладки Events (События)

Отметим еще одну полезную особенность программы HomeSite. В ней можно щелкнуть внутри любого тега правой кнопкой мыши и выбрать из контекстного меню пункт Edit Tag (Правка тега). После этого открывается диалоговое окно Редактора тегов (Tag Editor), в котором тоже очень удобно устанавливать значения всех доступных атрибутов.

Кстати, еще одна интересная возможность заключается в том, что теги И можно “сворачивать” командой Collapse Tag (Свернуть тег) из контекстного меню. При этом содержимое тега (все, что находится между его открывающим и закрывающим элементами, например, между <BODY> и </BODY> ) свернется в небольшой значок-кнопку. Это полезно при редактировании больших файлов, если надо быстро окинуть взглядом содержимое всей веб.

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

границы. В контекстном меню имеется также команда Collapse All Identical QS (Свернуть все идентичные теги), которая сворачивает содержимое всех тегов, идентичных данному по имени. Например, если при подаче этой команды был выделен тег <TR>, то в значки свернется содержимое всех гов <TR> , имеющихся в файле. Чтобы снова развернуть эти значки в текст, щелкните правой кнопкой мыши в любом месте панели редактирования и выберите в контекстном меню пункт Expand All (Развернуть все).

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

Создание графических карт ссылок

Для создания графической карты ссылок служит кнопка New Image Map (Создать изображение-карту) на верхней панели инструментов. Она открывает диалоговое окно, в котором можно выбрать какое-либо изображение, уже имеющееся на странице, или загрузить новое. После этого открывается окно редактора графической карты ссылок (Image Map Editor)

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

инструмента Стрелка можно легко отредактировать местоположение задан ных областей. После определения каждой области автоматически откры вается окно, в котором выбирают URL-адреса гиперссылок (атрибут HREF= тега <AREA>). Таким образом, создание графической карты ссылок пре вращается из сложного и утомительного занятия (каким оно всегда раньше считалось) в легкую и приятную процедуру.

Итак, мы рассмотрели некоторые полезные возможности панели редак тирования. Однако помимо вкладки Edit (Правка) на ней имеются еще две вкладки.

Предварительный просмотр страницы

Вторая вкладка называется Browse (Просмотр). На ней страница отобража ется в том виде, в котором она будет видна в броузере. Собственно говоря, кроме как для просмотра, эта вкладка ни для чего больше не предназна чена. Однако у нее тоже есть несколько особенностей.

Дело в том, что программа Homesite может использовать для отображения содержимого веб-страницы либо свой встроенный броузер, либо броузеры Internet Explorer и Netscape. При этом никакие внешние программы не запус каются — все содержимое отображается в окне редактирования, хотя фак тически при этом могут работать Internet Explorer или Netscape.

Встроенный броузер рекомендуется использовать только в тех случаях, когда нет ни Internet Explorer версии хотя бы 3.01 (более ранние версии этого броузера не способны встраиваться в Homesite), ни Netscape. Встроенный броузер не поддерживает ни фреймы, ни сценарии, ни большинство ново введений HTML 4.0. Кроме того, у него иногда (хотя и редко) возникают проблемы с отображением русских шрифтов.

Напротив, использовать броузеры Internet Explorer или Netscape в качестве внутреннего средства просмотра очень удобно, поскольку так можно про- сматривать содержимое своей веб-страницы в “настоящем” броузере, не запуская внешнюю программу. Впрочем, просмотр страницы во внешнем броузере тоже предусмотрен. Для этого служит кнопка со значком External Browser (Внешний броузер) на инструментальной панели. Нажав на нее, можно увидеть список внешних броузеров, установленных на компьютере, и, выбрав из списка какой-либо броузер, просмотреть в нем содержимое страницы. Если никаких броузеров в списке нет, их можно добавить вручную командой Options > Configure External Browsers (Параметры > Настройка внешних броузеров). А для того чтобы указать, какой броузер будет использоваться в качестве внутреннего, выберите из меню Options (Параметры) пункт Settings (Настройки) и далее в левой части открывшегося окна — пункт Browse (Просмотр).

Дретья вкладка панели редактирования — Design (Оформление). Ее средства предоставляют редактор веб-страниц, работающий по принципу WYSIWYG. Поскольку своего встроенного WYSZWYG-редактора в программе Homesite нет, используются средства, встроенные в броузер Internet Explorer 4.01. Если на компьютере нет этой (или более поздней версии) программы, средствами вкладки Design (Оформление) воспользоваться нельзя. Однако мы и так не рекомендуем ими пользоваться, поскольку после этого весь исходный код может быть переформатирован, вплоть до замены одних тегов другими, без возможности восстановления. Кроме того, с отображением русских шрифтов здесь тоже иногда возникают проблемы. Кстати, если выбрать в меню Options (Параметры) пункт Settings (Настройки) и далее пункт Design (Оформление), то можно установить флажок Disable (hide) design tab (Скрыть вкладку Оформление), чтобы вообще убрать эту вкладку с экрана. На всякий случай.

В программе Homesite есть еще много интересных возможностей, таких, как автоматическое изменение размера окна внутреннего броузера (до 640х480 или 800х600), поиск и замена текстовых фрагментов во всех файлах проекта или папки, отображение внутреннего броузера под окном редактирования (с “почти синхронным” отображением вносимых изменений) и пр. Однако обо всем невозможно рассказать в небольшой главе. Мы познакомили вас с основными возможностями этой замечательной программы, а остальные вы легко обнаружите сами в процессе работы.


2.1

2. Основные средства языка HTML

2.1. Простейшее форматирование текста

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

В качестве примера продолжим форматирование страницы нашего несуществующего писателя Сергея Сергеева. Предположим, что за вступительным текстом, который мы начали форматировать в разделе 1.2, мы должны расположить два его рассказа (он же писатель!). Каждый рассказ имеет название, подзаголовок и небольшой эпиграф.

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

Управление выравниванием текста

В данном случае нам потребуется такой атрибут, как выравнивание (выключка) текста. Он может употребляться с разными тегами. Поскольку на нашей страничке и заголовок, и эпиграф должны быть отделены друг от друга и от основного текста, имеет смысл употребить тег <Р> . Каждый фрагмент текста, заключенный между тегами <Р> и </Р> , будет представлять собой отдельный абзац:

<Р>Это первый абзац.</Р> <Р>Это второй абзац.</Р> <Р>Это третий абзац и т. д.</Р>

Чтобы выровнять заголовок по центру страницы, можно написать следующее:

<Р ALIGN="center">3AГOЛOBOK РАССКАЗА № !</Р>

Вы, очевидно, уже поняли, что атрибут ALIGN= означает выравнивание. Ему присвоено значение "center" для выравнивания текста по центру страницы. Между атрибутом и его значением всегда должен стоять знак равенства. Для того чтобы расположить эпиграф по правому краю, надо, соответственно, атрибуту ALIGN= присвоить значение "right":

<Р ALIGN="right">ЭПИГРАФ</P>

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

<HTML>

<HEAD>

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">

<TITLE>Домашняя страница Сергея Cepreeвa</TITLE>

</HEAD>

<BODY>

<FONT FACE="Times New Roman"><P>Домашняя страница Сергея Сергеева<BR>

<BR>

Сергей Сергеев - писатель-авангардист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.<BR>

<BR>

Некоторые его рассказы вы можете прочитать прямо здесь. </P>

<P ALIGN="CENTER">ИBAH-ЦAPEBИЧ И СЕРЫЙ ЗАЯЦ<BR>

сказка</Р></P>

<P ALIGN="RIGHT">Hy, погоди!.. <BR>

(Из мультфильма)</P>

<P>Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный. Однако тоскливо было у него на душе - как встанет утром с постели царской, так и начнет горевать, и горюет до вечера.<BR>

Долго ли, коротко ли, ... (тут располагается еще несколько абзацев, разделенных тегом BR, хотя это не единственный способ разделения абзацев)...<BR>

И они жили долго и счастливо и умерли в один день. </P>

<P ALIGN="CENTER">MOЛOTOK<BR>

рассказ</P>

<P ALIGN="RIGHT">Мы кузнецы, и дух наш молод.<BR>

(Из песни)</P>

<P>Это случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа) </P></FONT>

</BODY>

</HTML>

Результат показан на рис. 2.1. Как видите, это весьма похоже на то, что было задумано. Однако сразу бросаются в глаза несколько недостатков. Во-первых, абзацы в основном тексте на вид плохо отделены друг от друга, хотя и разделены тегом <BR> .

Рис. 2.1. Иллюстрация применения атрибута ALIGN

Оформление абзацев

Вообще говоря, для разделения абзацев вместо тега <BR> можно также использовать тег <Р> . Он, надо сказать, и был создан для этого. Но поскольку придумывали его не у нас в России, то он делит абзацы в соответствии с зарубежными правилами книгопечатания — между абзацами пропускается строка, а сам абзац начинается без отступа слева (“красной строки”). Такое оформление непривычно для нас, и поэтому попробуем отформатировать абзацы по-другому — без пропуска строки и с отступом слева.

Собственно, используя тег <BR> вместо тега <Р> , мы уже избежали пропуска строки перед каждым абзацем. Теперь попробуем создать отступ. в НTML изначально не было предусмотрено средств для этого, поэтому придется схитрить.

Если вы еще помните, в былые времена в примитивных текстовых редакторах некоторые использовали для отступа несколько пробелов, как на пишущей машинке. Здесь можно попробовать применить этот допотопный прием. Правда, “в лоб” он работать не будет, поскольку броузеры игнорируют лишние пробелы. Однако мы можем поставить специальный символ, называемый неразрывным пробелом. Он никогда не игнорируется, и несколько таких символов вполне могут заменить нам отступ первой строки. Для того чтобы создать неразрывный пробел, следует ввести:

&nbsp;

Поясним, что в языке HTML подобная конструкция всегда используется для ввода так называемых специальных символов. Как только броузер встречает в тексте знак амперсенд (&), он начинает интерпретировать сле-дующие за ним буквы как код специального символа. Так продолжается до тех пор, пока не встретится точка с запятой. Специальные символы используются, в частности, для кодирования букв с различными “добав-ками” типа селиля, циркумфлекса и пр. (для текстов, например, на фран-цузском языке), ввода знаков торговой марки и авторского права, символов денежных единиц, знаков “больше” и “меньше” и т. д.

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

Оформление заголовков

Посмотрим еще раз на нашу страничку. Еще один ее недостаток заключается в том, что весь текст написан шрифтом одного размера. Вообще говоря заголовки выделяют более крупным шрифтом (причем обычно полужирным). Для того чтобы выделять заголовки, в HTML существуют так называемые теги заголовков. Это <Н1>, <Н2>, <НЗ>, <Н4>, <Н5> и <Н6> (и из закрывающие теги). Для самых крупных заголовков можно использовав тег <Н1> , для заголовков помельче — <Н2> и так далее. Например, так:

<Н2>ИВАН-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ<ВR> сказка</Н2>

Однако обратите внимание на то, что для выравнивания по центру нужно приложить дополнительные усилия, например поместить соответствующий тег внутрь тега заголовка (то есть в данном случае между тегами <Н2> и </Н2> ):

<Н2><Р ALING="сеntег">ИВАН-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ<ВR> сказка</Р></Н2> Если этого не сделать, то заголовок будет выровнен по левому краю.

В нашем случае имеет смысл использовать для заголовков рассказа тем <Н2> , а для заголовка всей странички — тег <Н1> (общий заголовок дол жен быть крупнее). Для выравнивания общего заголовка по центру мы можем написать так:

<H1><DIV ALING="сеntег">Домашняя страница Сергея Сергеева</DIV></Н1>

Обратите внимание на то, что вместо тега <Р> для выравнивания мы: использовали тег <DIV> . Этот тег означает разделитель и определяет фрагмент, который можно наделить какими-либо стилевыми свойствами, Текст, расположенный между тегами <DIV> и </DIV> , в большинстве броу зеров также отделяется от остального текста с помощью символа перевода строки (если не заданы еще какие-либо параметры). Запомните этот тег — впоследствии нам придется употреблять его очень часто.

Пойдем дальше. Вы, наверное, обратили внимание на то, что в предыду щем примере основной текст рассказов был заключен в тег < Р ALIGN="left"> . Здесь значение "left" означает выравнивание по левому краю, однако это значение атрибута ALIGN= определено по умолчанию. То есть, для опреде-

пия абзаца, выровненного по левому краю, достаточно было просто "ставить тег <Р>. Однако текст рассказа обычно смотрится лучше, если него ровные оба края, а не только левый — мы к этому привыкли по бумажным” изданиям. Чтобы выровнять текст по обоим краям, можно добавить атрибут ALIGN= со значением "justify". Но следует иметь в виду, о такое выравнивание не поддерживалось в старых версиях броузеров. (юузеры Internet Explorer и Netscape Navigator поддерживают его только начиная со своих четвертых версий.

Горизонтальная линейка

Более, на нашей страничке хотелось бы визуально отделить рассказы от вступительного текста. Это можно сделать с помощью горизонтальной черты. В принципе, для этого достаточно в нужном месте поставить тег <BR> (он не имеет закрывающего тега). Однако в этом случае горизонтальная черта займет всю ширину страницы, что будет смотреться неопрятно. Для определения ширины горизонтальной черты можно задать атрибут WIDTH=, например, так:

<HR WIDTH="75%">

В этом случае горизонтальная линия займет 75% от полной ширины экранной страницы. Можно также определять ширину линии и в пикселах ( экранных точках). Например, запись <HR WIDTH="75"> определит ширину линии в 75 пикселов (это получится очень короткая линия). Если хотите, можете определить также толщину линии, установив атрибут SIZE=.

Некоторые проблемы могут возникнуть, если мы захотим оставить немного Свободного пространства между вступительным текстом и горизонталь ной линией (в данном случае это уместно, так как между линией и заголовком, определенным тегом <Н2> , пространство довольно большое, и желательно соблюсти некоторый баланс). Дело в том, что если поставить перед линией тег <BR> , то большинство броузеров его проигнорируют. Выход можно найти, если после <BR> вставить неразрывный пробел или вместо <BR> использовать “пустой” абзац:

<P></P><HR WIDTH="75%">

И то и другое не очень эстетично с точки зрения кода. Правда, если страничка делается для броузеров Netscape (версии 3 и более поздних), можно использовать тег <SPACER> , чтобы задать вертикальный отступ:

<SPACER TYPE="vertical" SIZE="25">

собственно говоря, это то, что нужно, но другие броузеры не поддерживают этот тег и поэтому просто проигнорируют его. Поэтому ограничимся пока тегом <BR> с неразрывным пробелом. А в главе 4 вы узнаете, как можно легко решать такие проблемы с помощью CSS (каскадных таблиц стилей).

Давайте посмотрим, что у нас получилось.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<title>Домашняя страница Сергея Cepreesa</title>

</head>

<body>

<h1><DIV aling="center">Домашняя страница Сергея Сергеева </div></h1>

<br> Сергей Сергеев - писатель-авангардист, автор 20 рассказов. <br>

В жизни большой любитель собак и компьютерных игр. <br> <br>

Некоторые его рассказы вы можете прочитать прямо здесь. <br>

<HR WIDTH="75%"> <H2><P ALIGN="center">ИBAH-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ <br>

сказка</p></H2>

<p align="right">Hy, погоди!.. <BR>(Из мультфильма)</Р>

<p align="justify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Жил да

был Иван-Царевич, и все у него было: и злато-серебро, и невест

полный дворец, и книжек много умных, и тренажерный зал огромный... <br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Долго ли, коротко ли ... <br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;И они жили долго и счастливо

и умерли в один день.</Р>

<HR WIDTH="75%">

<h2><p align="center">MOЛOTOK <br> рассказ</p></h2>

<p ALIGN="right">Mы кузнецы, и дух наш молод. <br> (Из песни)</P>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Это

случилось очень давно, уж и не помню в каком году, в каком веке

и в каком тысячелетии... (Здесь располагается текст рассказа)

</BODY>

</HTML>

Результат наших трудов представлен на рис. 2.2. Что ж, страничка посте пенно становится все лучше. Но, не правда ли, хочется сделать вступи-

Рис. 2.2. Применение заголовочных стилей

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

Управление шрифтом

Чтобы изменить размер шрифта, можно использовать тег <FONT> с атрибутом SIZE=. Вообще говоря, WWW-консорциум не особенно рекомендует использовать тег <FONT> в HTML 4.0. Мы считаем, что злоупотреблять им действительно не нужно, когда есть возможность использования каскадных таблиц стилей CSS, о чем мы поговорим в главе 4. Однако иногда для мелких корректив этот тег бывает очень удобен. Например, если мы поставим перед вступительным текстом тег

<FONT SIZE="+1">

f поcле него — закрывающий тег </FONT>, то весь текст, оказавшийся между этими тегами, будет отображен шрифтом на один “уровень” круп-нее обычного.

Возникает вопрос: а каков размер “обычного” шрифта? В языке HTML для тега <FONT> были определены семь основных размеров шрифта, измеряемых не в пунктах, а в некоторых условных единицах — от 1 до 7. Как правило, обычный шрифт имеет размер “З”, если не определено иное с помощью тега <BASEFONT> (например, так: <BASEFONT SIZE="6">) . В послед- нее время такое определение размеров не рекомендуется, поскольку с помощью CSS можно определить размеры шрифта в любых привычных единицах.

Необходимо различать записи <FONT SIZE="+1" и <FONT SIZE="1"> . В пер- вом случае указывается относительный размер шрифта, а во втором — абсолютный. Соответственно, для временного уменьшения размера шрифта можно использовать запись <FONT SIZE="-1"> . Можно использо- вать также значения "+2", "-2", "+3" и т. д. Кстати, для увеличения или уменьшения шрифта на одну единицу можно использовать также теги <BIG> и <SMALL> (они используются с закрывающими тегами).

Теперь давайте выделим еще некоторые элементы нашей страницы. Чтобы отобразить подзаголовки рассказов курсивом, их можно поместить между тегами <I> и </I> :

<Н2><Р АLIGN+"center">ИВАН-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ<ВК> <I>сказка</I></Р></Н2>

Такой же результат, как тег <I> , дает тег <ЕМ> . Отличие их в том, что тег <ЕМ> определяет лишь логически выделенный фрагмент, который броузеры обычно отображают курсивом, а тег <I> — это явное указание на кур сив. Впрочем, это уже несущественные детали.

Мы можем также выделить фамилию нашего героя во вступительном тексте полужирным шрифтом, используя тег <В> :

<В>Сергей Сергеев</В> - писатель-авангардист, автор 20 рассказов.

Такой же результат даст использование тега <STRONG> . Более гибко управлять выделением можно с помощью CSS

Для выделения какой-либо части текста можно использовать подчеркивание, поместив текст между тегами <U> и </U> . Однако злоупотреблять этим не следует, поскольку подчеркнутый текст в WWW ассоциируется с гиперссылками и читатель будет весьма разочарован, когда щелчок мыши по подчеркнутому тексту ни к чему не приведет.

Иногда требуется также зачеркнуть отдельные слова в тексте (например, при снижении цен на товары обычно указывают старую цену в зачеркнутом виде). Для этого служит тег <STRIKE>:

Старая цена: <STRIKE>168 рублей </STRIKE> Новая цена: <FONT SIZE="+1">102 рубля</FONТ>

Результат представлен на рис. 2.3. Некоторые броузеры понимают также сокращенное написание этого тега — <S> . Однако для хорошей совмести мости пользуйтесь лучше тегом <STRIKE> (пока возможно, совместимость

со всеми броузерами все же лучше поддерживать, тем более что на данном этапе это совсем несложно).

Рис. 2.3. Применение зачеркнутого текста

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

Цветовое оформление

Для этого проще всего установить соответствующие атрибуты тега <BODY> . Атрибут ТЕХТ= определяет цвет текста на страничке, а атрибут BGCOLOR= — цвет фона. Названия цветов можно вводить по названиям, например: "black" (черный), "white" (белый), "yellow" (желтый), "green" (зеленый), "fuchsia" (сиреневый) и т. д. Существует довольно много названий цветов, которые можно использовать в HTML, однако можно получить любой из цветов, введя его шестнадцатеричный номер. Причем это не так сложно, как может показаться.

Шестнадцатеричный номер цвета должен состоять из шести цифр. Первые две означают интенсивность красной составляющей, вторые две — зеленой и последние две — синей. Таким образом, красный цвет обозначается как FFOOOO, зеленый — OOFFOO и синий — OOOOFF. Цвет с номером 000000 — чер- ный (нет ни одной составляющей), a FFFFFF — белый. Если это понятно, то можно поэкспериментировать с интенсивностью каждой составляющей отдельно. Если FFOOOO — это красный цвет, то 880000 — уже темно-красный, а 440000 — красно-коричневый; 220000 похож на коричневый, а 110000 — черный с красноватым оттенком. Точно так же OOFFOO — это яркий зеле ный, ООААОО — приятный лиственно-зеленый, 007700 — темно-зеленый,

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

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

<BODY BGCOLOR="#BABAAO" TEXT="#1D1D18">

Это даст при просмотре одинаковый коричневатый оттенок и цвета, и фона, однако цвет фона будет более тяготеть к серебряно-белому, а цвет текста — к темно коричневому. Давайте посмотрим, что у нас получилось.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<title>Домашняя страница Сергея Cepreesa</title>

</head>

<body bgcolor="#babaa0" text="1d1d18">

<h1><DIV aling="center">Домашняя страница Сергея Сергеева </div></h1>

<br> Сергей Сергеев - писатель-авангардист, автор 20 рассказов. <br>

В жизни большой любитель собак и компьютерных игр. <br> <br>

Некоторые его рассказы вы можете прочитать прямо здесь. <br>

<HR WIDTH="75%"> <H2><P ALIGN="center">ИBAH-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ <br>

сказка</p></H2>

<p align="right">Hy, погоди!.. <BR>(Из мультфильма)</Р>

<p align="justify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Жил да

был Иван-Царевич, и все у него было: и злато-серебро, и невест

полный дворец, и книжек много умных, и тренажерный зал огромный... <br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Долго ли, коротко ли ... <br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;И они жили долго и счастливо

и умерли в один день.</Р>

<HR WIDTH="75%">

<h2><p align="center">MOЛOTOK <br> рассказ</p></h2>

<p ALIGN="right">Mы кузнецы, и дух наш молод. <br> (Из песни)</P>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Это

случилось очень давно, уж и не помню в каком году, в каком веке

и в каком тысячелетии... (Здесь располагается текст рассказа)

</BODY>

</HTML>

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

Дополнительные варианты оформления

отображают текст, находящийся между тегами <CITY></CITY> курсивом. Например, если вы напишете следующее"

А.С. Пушкин сам говорил,

что он <CITY>лиру посвятил народу

своему</CITY> по этому есть все основания считать, что судьба русского народа

была для него не безразлична.

то большинство броузеров отобразят это так. как показано на рис 2.5(ниже)

Об этом хорошо сказал С.С.Сергеев в своей бессмертной повести "Обыкновенный обрыв":

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

Но еще лучше ни о чем не мечтать, а спокойно почитать научные статьи и трезво оценить ситуацию.

Рис. 2.5. Применение длинной цитаты

также отобразить и обычные типографские кавычки (“? ”) вместо машинописных (" "). Запись Книга &laquo; Путеводитель по Атлантиде &raquо; отобразится в броузере так:

Книга “Путеводитель по Атлантиде”

Теперь давайте представим себе, что нам надо воспроизвести на веб-страничке фрагмент кода-HTML и проиллюстрировать его отображение. Причем код HTML мы хотим выделить моноширинным шрифтом (как это обычно и делается, например, в этой книге). Для этого можно применить тег <CODE> , как показано ниже.

Если вы напишете следующий код: <br>

<code> &lt;hr WIDTH="80%" SIZE="15"&gt;,

</code><br> то это отобразится так:

<HR WIDTH="80%" SIZE="15">

Нa рис. 2.6 показано, как это отобразится в броузере. Помимо тега <CODE> , обратите внимание на употребление специальных символов &lt; и &gt; для отображения угловых скобок,

Вместо тега <CODE> можно также употребить и тег <ТТ> . Разница между ними такая же, как между тегами <ЕМ> и <I> . То есть, тег <CODE> определяет логический фрагмент, который обычно выводится моноширинным!

То есть шрифтом, в котором все символы имеют одинаковую ширину, на манер пишущей машинки.

Рис. 2.6. Отображение исходного кода программ в броузере

шрифтом, как код, а тег <ТТ> просто применяет к фрагменту моноширинный шрифт. Разница, прямо скажем, небольшая.

Для отображения больших фрагментов кода существует еще один тег — <LISTING> . Весь текст, заключенный между ним и его закрывающим тегом, отображается не просто моноширинным шрифтом, а еще и с пропуском строки до и после кода, и обычно более мелким шрифтом. Кроме того, в этом тексте сохраняется исходное форматирование (как при использовании тега <PRE> ). Однако использование этого тега уже давно не рекомендовано WWW-консорциумом.


2.2

2.2. Самое главное на любой веб-странице — гиперссылки

В предыдущем разделе мы рассмотрели различные способы форматирования текста веб-страницы. Однако созданная нами в качестве примера “Домашняя страница Сергея Сергеева” имеет существенный недостаток: она представляет собой голый текст. И дело тут вовсе не в отсутствии графики или звуковых фрагментов (графика и звук, конечно, украшают страничку, но в данном случае не это главное). Дело в отсутствии гиперссылок. Гилерссылки — контекстные связи между расположенными в Интернете материалами. Они являются основой построения World Wide Web. Обычно пользователи любят страницы, насыщенные гиперссылками, и это естественно: приятно, когда есть возможность легко получить более подробную информацию по каждой представленной теме.

В принципе, любое слово, встречающееся на веб-странице, можно превратить в гиперссылку, если известны какие-либо другие страницы, описывающие этот предмет более подробно. Так, например, на странице, посвященной описанию жизни в блокадном Ленинграде, в том месте, где речь идет об исполнении седьмой симфонии Шостаковича, помещена гиперссылка на страницу с биографией этого композитора. А на странице, посвященной компьютерной игре Quake, в углу указано, что теперь в нее можно играть и на компьютерах с операционной системой Linux — и в этом месте есть гиперссылка на страницу, с которой можно загрузить дистрибутив этой операционной системы. Щелкая кнопкой мыши по гиперссылкам, можно в принципе обойти хоть весь Интернет (точнее, его службу WWW).

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

• ссылки в другие места той же страницы; • ссылки на другие страницы этого же сайта или сервера;

• ссылки на страницы, расположенные на любом другом сервере в Интернете.

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

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

Чтобы это сделать, надо сначала определить места, где эти рассказы начинаются, как “якоря” (места, к которым можно будет быстро переместиться). Для этого используют тег <А> . Это можно сделать, например, так:

<A NAME="skazka">ИВАН- ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ</А>

В данном случае мы определяем атрибут NAME= — имя якоря. По этому имени мы и будем на него ссылаться.

Для установки гиперссылки также используется тег <А> , но с установленным атрибутом HREF=. Значение этого атрибута определяет, что отобразится на экране, если пользователь щелкнет кнопкой мыши на гиперссылке. Чтобы сослаться на якорь, нужно просто указать в качестве значения HREF= имя этого якоря, перед которым расположен знак #:

<A HREF="#skazka">Сказка &laquo;Иван-царевич и серый заяц&raquо;</А>

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

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

Точно таким же образом можно поставить гиперссылку на второй рассказ. По умолчанию в большинстве броузеров гиперссылки отображаются синим цветом, что совершенно не гармонирует с цветовой гаммой нашей странички. К счастью, мы можем сами задать нужный цвет отображения гиперссылок. Для этого нужно в теге <BODY> установить значение атрибута LINK=. Цвет можно выбрать по своему усмотрению, можно даже сделать гиперссылки тем же цветом, что и основной текст. Но вот этого как раз делать не рекомендуется, поскольку читатель не сможет быстро понять, где гиперссылка, а где нет. Обычно лучше всего подобрать цвет, близкий по оттенку к основному, однако отличающийся от него, например, по яркости. В нашем случае можно написать так:

<BODY BGCOLOR="#BABAAO" TEXT="#1D1D18" LINK="#634438">

Однако этого недостаточно. Дело в том, что броузер обычно отображает гиперссылки, которыми читатель еще не пользовался, одним цветом, а “посещенные” — другим. Этот цвет выбирается с помощью атрибута VLINK= тега <BODY> . Кроме того, есть еще атрибут ALINK=, который определяет цвет так называемой активной ссылки, то есть той, на которой в данный момент происходит щелчок кнопкой мыши. В большинстве случаев он почти не заметен (ведь появляется он только на долю секунды, если только у читателя нет привычки нажать кнопку мыши и долго ее не отпускать). Полное определение цветовой схемы страницы в теге <BODY> может выглядеть так:

<HTML>

<HEAD>

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">

<META NAME="Generator" CONTENT="Microsoft Word 97">

<TITLE>Домашняя страница Сергея Cepreesa</TITLE>

<META NAME="Template" CONTENT="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">

</HEAD>

<BODY TEXT="#000000" BGCOLOR="#babaa0">

<DIV aling="center"><h1>Домашняя страница Сергея Сергеева</h1> </div>

</FONT><FONT SIZE=1><P><BR>

<div align="center"><a href="#skazka">Сказка &laquo;Иван-царевич и серый заяц&raquo;</A>&nbsp;

<A HREF="#rasskaz">Рассказ &laquo;Молоток&raquo;</a></div>

</FONT><B><FONT FACE="Times New Roman">Сергей Сергеев - писатель-авангардист, автор 20 рассказов. <BR>

В жизни большой любитель собак и компьютерных игр. <BR>

<BR>

Некоторые его рассказы вы можете прочитать прямо здесь. </P>

</FONT><P><HR WIDTH="75%"></P>

</B><FONT FACE="Times New Roman"><H2 ALIGN="CENTER">ИBAH-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ <BR>

сказка</H2>

<P ALIGN="RIGHT">Hy, погоди!.. <BR>

(Из мультфильма)</Р></FONT> </P>

<FONT FACE="Times New Roman"><P ALIGN="JUSTIFY">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный... <BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Долго ли, коротко ли ... <BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;И они жили долго и счастливо и умерли в один день.</Р></FONT> </P>

<P><HR WIDTH="75%"></P>

<FONT FACE="Times New Roman"><H2 ALIGN="CENTER">MOЛOTOK <BR>

рассказ</H2>

<P ALIGN="RIGHT">Mы кузнецы, и дух наш молод. <BR>

(Из песни)</P>

<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Это случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа) </P></FONT>

</BODY>

</HTML>

Результат показан на рис. 2.7. Если мы теперь щелкнем на какой-либо из гиперссылок, то страница “скакнет” вниз, так, чтобы текст нашего якоря отображался вверху экрана. (Однако, если при этом для заполнения экране не будет хватать текста, то текст якоря может оказаться не на самом верх страницы, а несколько ниже.)

Рис. 2.7. Применение внутренних гиперссылок

Гиперссылки в пределах сайта

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

В нашем примере давайте выделим в отдельные файлы вступительный текст и каждый из рассказов. Основной файл назовем sergeev.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Домашняя страница Сергея Cepreeвa</TITLE>

</HEAD>

<BODY
BGCOLOR="#BABAAO" TEXT="#1D1D18"
LINK="#634438" VLINK="#634438"
ALINK="Black'">

<H1><DIV ALIGN="center">Дoмaшняя страница Сергея Cepreeaa</DIV> </H1>

<DIV ALIGN="center"><A HREF="skazka.html">CKА3KА &laquo;ИBАH- царевич и серый зaяц&raquo;</A>&nbsp;

<A HREF="rasskaz.html">Paccкaз &laquo;Moлоток &raquo;</A></DIV> <BR>

<FONT SIZE="+l"><B>Cepгeй Сергеев</В> - писатель-авангардист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.<ВR><ВR>

Некоторые его рассказы вы можете прочитать прямо здесь.<BR>&nbsp;</FONT>

<HR WIDTH="75%"> </BODY> </HTML>

Затем создадим файл первого рассказа. Назовем его skazka.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD>

<TITLE>ИBAH-ЦAPEBИЧ И СЕРЫЙ 3AЯЦ,</TITLE>

</HEAD>

<BODY
BGCOLOR="#BABAAO" TEXT="#1D1D18"
LINK="#634438" VLINK="#634438"
ALINK="Black">

<H2XP ALIGN="center">ИBAH-ЦAPEBИЧ И СЕРЫЙ ЗАЯЦ<ВR> <I>сказка</I></Р></Н2>

<Р ALIGN="right"XFONT SIZE="-l">Hy, погоди!.. <BR> <I> (Из мультфильма) </I></FONT></P>

<Р ALIGN="justify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец...<BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Долго ли, коротко ли ... <BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;И они жили долго и счастливо и умерли в один день. </Р>

<HR WIDTH="75%"> <А НRЕF="sergeev.html">Вернуться на главную страницу</А>

</BODY>

</HTML>

И, наконец, создадим файл второго рассказа, rasskaz.html.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>MOЛOTOK</TITLE>

</HEAD>

<BODY BGCOLOR="#BABAAO" TEXT="#1D1D18" LINK="#634438 " VLINK="#634438" ALINK="Black">

<H2XP ALIGN="center">MOЛOTOK<BR> <i>рассказ</i></Р></Н2>

<P ALIGN="right"><FONT SIZE="-l">Mы кузнецы, и дух наш молод. <BR><I> (Из песни) </I></FONT></P>

<Р ALIGN="justify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Это случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа) </Р>

<HR WIDTH="75%"> <А НREF="sergeev.htm1">Вернуться на главную страницу</А>

</BODY>

</HTML>

Как видите, чтобы установить гиперссылку на другой файл, необходимо в качестве значения атрибута HREF= указать имя этого файла:

<A HREF="skazka.html">Cкaзкa &laquo;Иван-царевич и серый зaяц&raquo;</A>

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

в нашем примере в конце каждого файла с рассказом мы поместили гиперссылку

<А НRЕF="sergeev.html">Вернуться на главную страницу</А>

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

Внешние гиперссылки

Однако гиперссылки можно устанавливать не только на файлы, содержа-щиеся в своем каталоге на сервере, но и на любые другие Интернет-ресурсы. В этом случае в качестве значения атрибута HREF= необходимо указать полный URL-appec ресурса, как показано ниже. Рассмотрим такой пример. Допустим, мы хотим сделать страничку, с которой можно легко попадать на излюбленные поисковые системы 1 . Естественно, для этого необходимо указывать полные URL-адреса этих сайтов, например, вот так:

Поисковая машина <А HREF="http://www.altavista.com">"Altavista" </А>

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

Один из выходов состоит в том, чтобы не загружать сайт поисковой машины в том же окне броузера, в которое была загружена наша веб-страница, а открыть ее в новом окне. Для этого нужно в теге <А> установить атрибут TARGET= со значением "_blank", следующим образом:

Поисковая машина <А HREF="http://www.altavista.corn" TARGET="_blank">"Altavista"</A><BR>

Давайте теперь вспомним, как задавать на страничке цвета и элементы форматирования текста, и посмотрим, что может получиться в целом.

<html>

<head>

<title>Поисковая машина</title>

</head>

<body BGCOLOR="#FPAEAE" TEXT="#480000" LINK="#C10000"

VLINK="#C10000" ALINK="#C10000">

<H1><DIV ALIGN="center">Поисковая машина</DIV></H1>

<br>

Если вы ищете в Интернете какую-либо информацию, вам помогут

следующие сайты:

<br><br>

Поисковая машина <A HREF="http://www.altavista.corn"

TARGET="_blank">"Altavista"</A><br>

Каталог ресурсов <A HREF="http://www.yahoo.corn"

TARGET="_blank">"Yahoo! "</A><br>

Поисковая машина <A HREF="http://www.yandex.ru"

TARGET="_blank">"Яndex"</A><br>

Поисковая машина <A HREF="http://www.aport.ru"

TARGET="_blank">"Anopт"</a>

</BODY>

</HTML>

Результат показан на рис. 2.8. Как видите, ничто не указывает на тот факт, что сайты поисковых систем будут загружаться в новое окно; пользователь увидит это только после щечка на гиперссылке.

Рис. 2.8. Применение гиперссылок для связей с удаленными серверами

Помимо значения "_blank", атрибут TARGET= может принимать еще значения "_self", "_top" и "_parent"; его значением может также быть имя любого окна. Однако все это мы рассмотрим позднее, Пока же запомните только, что значение "_blank" вызывает загрузку странички в новое окно броузера, а значение "_self" — в то же окно, в котором был сделан щелчок на гиперссылке. Собственно говоря, значение "_self определено по умолчанию.

И еще одно: не следует слишком злоупотреблять значением TARGET="_blank", поскольку при множестве открытых окон броузера читатель в них может легко запутаться и у него останется негативное ощущение. А вообще, гиперссылки всегда очень помогают в навигации в Интернете. Их никогда не бывает слишком много.


2.3

2.3. Как создать списки на веб-странице

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

В качестве первого примера давайте рассмотрим веб-страницу гипотетической фирмы “Лентяй”. Допустим, мы сначала хотим перечислить предоставляемые услуги, а затем указать последовательность действий, необходимых для их заказа.

Маркированные и нумерованные списки

Перечисление услуг хорошо смотрится в виде маркированного списка. Для его организации применяется тег <UL> . Все, что находится между ним и его открывающим тегом ( </UL> ), считается маркированным списком. Каждый элемент списка должен быть при этом обозначен тегом <LI>. Этот тег можно употреблять без закрывающего (хотя можно и с ним). То есть, можно написать:

<LI>Вкручивание электрических лампочек или

<LI>Вкручивание электрических лампочек</LI>

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

Что о касается перечисления порядка действий для заказа, то его целесооб- разно организовать в виде нумерованного списка. Для этого служит тег <OL> , а элементы списка также обозначаются тегом <LI> . И нумерованные, и маркированные списки в большинстве броузеров выделяются небольшим отступом. Итак, давайте посмотрим, как может выглядеть эта страничка.

<HTML>

<HEAD>

<TITLE> фирма "ЛЕНТЯЙ"</TITLE>

</HEAD>

<BODY BGCOLOR="#D2FFFF" TEXT="#003737" LINK="#006A6A"

VLINK="#006A6A" ALINK="#006A6A">

<DIV ALIGN""center"><H1> фирма &laquo;ЛЕНТЯЙ &laquo;</H1></DIV>

<FONT SIZE="+l">Haшa фирма предоставляет следующие услуги </FONT>

<UL> <li>Вкручивание электрических лампочек

<li>Подметание пола

<li>Вынесение мусора из квартиры

<li>Мытье посуды

<li>Дефрагментация жестких дисков </UL>

<FONT SIZE="+l">Чтобы воспользоваться нашими услугами,следует: </FONT>

<OL>

<li>Зарегистрироваться (<a HRЕF="#reg.html"> здесь</a>)

<li>Заполнить форму заказа

(<a HRЕF="forml.html">здесь</a>)

<li>Получив письмо с паролем, послать пустой ответ

<li>Заполнить форму-подтверждение заказа

(<a HRЕF="form2.html">здесь</a>)

<li>Приготовить деньги для оплаты услуг </OL>

</BODY>

</HTML>

Рис. 2.9. Применение маркированного и нумерованного списков

Результат показан на рис. 2.9. Как видите, мы здесь не употребляли закрывающий тег </LI> . Броузер обычно все равно понимает, где кончается элемент списка, поскольку после любого элемента стоит либо тег следующего элемента <U> , либо тег завершения списка </UL> или </OL>.

Другой вопрос, что будет, если код написан некорректно: например, указаны теги <LI> без тега списка <OL> или <UL> , или в списке есть элементы без тега <LI> ?

Вообще говоря, такого допускать не следует, так как некоторые “строгие” браузеры в этом случае не будут отображать практически ничего. Большинство популярных броузеров, правда, попытаются угодить даже автору странички, написавшему такой код. Например, Internet Explorer 5, если встретит теги <LI> без тега начала списка, интерпретирует их как маркирован ный список, хотя и не будет выделять его отступом, а не помеченные тегом <LI> элементы списка оставит без маркера. Однако, повторяю, это из ряда вон выходящие случаи.

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

<UL>

<UL>

<UL>

</UL>

</UL>

</UL>

Разумеется, отступы здесь обозначены только для наглядности — чтобы не перепутать, какой закрывающий тег к какому открывающему тегу относится. Далее, при вложении нескольких маркированных списков хочется каждый из них обозначить своим типом маркера. Некоторые броузеры так и делают по умолчанию. Например, Internet Explorer элементы первого списка из серии вложенных обозначает закрашенным кружком, элементы второго — незакрашенным кружком, а элементы всех следующих — квадратиком. Однако, во-первых, так поступают не все броузеры, а во-вторых, нам может захотеться изменить порядок маркеров. Для явного определения типа маркера в теге <UL> следует установить атрибут TYPE=. У него могут быть три значения: "disc", "square" и "circle", что означает, соответственно, закрашенный кружок, квадратик и незакрашенный кружок.

В теге нумерованного списка <OL> можно установить атрибут TYPE= для определения типа нумерации. Если не указано ничего или установлено значение TYPE="1", то нумерация происходит обычными цифрами. Если установить TYPE="I" или "i", то получится нумерацию римскими цифрами (соответственно, с использованием прописных или строчных букв).

И, наконец, для буквенных обозначений элементов списка устанавливают атрибут TYPE="A" или "а". Кроме того, иногда может потребоваться начать нумерацию не с единицы, а с какого-нибудь иного числа. Для этого существует атрибут START=. Например, запись <OL START="43"> вызовет нумерацию элементов списка, начиная с числа 43. Далее пойдут элементы с номерами 44, 45 и т. д.

Может возникнуть естественный вопрос: а как использовать другие типы маркеров списков — разнообразные галочки, цветные кружки и прочие, которые мы так часто видим в WWW,? Действительно, такая возможность есть, однако мы рассмотрим ее несколько позже, в разделе Si.3. А пока приведем пример веб-странички фирмы “Лентяй” с использованием вложенных списков:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<head>

<title>Фирма "ЛЕНТЯЙ"</title>

</head>

<body BGCOLOR="#D2FFFF" TEXT="#003737" LINK="#006A6A"

VLINK="#006A6A" ALINK="#006A6A">

<DIV ALING="center"><H1>Фирма &laquo;ЛEHTЯЙ&raquo;</H1></DIV>

<FONT SIZE="+l">Haшa фирма предоставляет следующие услуги:

</FONТ>

<UL TYPE="disc">

<LI>Бытовые услуги

<UL TYPE="square">

<LI>Вкручивание электрических лампочек

<LI>Услуги по наведению чистоты

<UL TYPE="circle">

<LI>Подметание пола

<LI>Вынесение мусора из квартиры

<LI>Мытье посуды

</UL>

</UL>

<LI>Приготовление пищи

<LI>Компьютерные услуги

<UL TYPE="square">

<LI>Дефрагментация жестких дисков

<LI>Переустановка Windows

</UL>

</UL>

<FONT SIZE="+1">Для того, чтобы воспользоваться нашими услугами,

следует:</FONT>

<OL>

<LI>Зарегистрироваться

(<A HREF="reg.html">здесь</A>)

<LI>Заполнить форму заказа

(<A HREF="forml.htm1">здесь</А>)

<LI>Пoдтвepдить заказ:

<OL TYPE="I">

<LI>Получив письмо с паролем подтверждения, послать пустой ответ,

нажав "Reply"

<LI>Заполнить форму-подтверждение заказа

(<A HREF="form2.html">здесь</A>)

</OL>

<LI>Приготовить деньги для оплаты услуг

</OL>

</body>

</html>

Результат показан на рис .2.10. Между прочим, при желании можно изменить вид маркера даже у отдельного элемента списка. Для этого следует установить атрибут TYPE= у тега <LI> . Однако это не будет смотреться очень хорошо, за исключением специальных случаев.

Мы пока намеренно не приводим примеры того, что могло бы быть в файлах reg.html, form! .html и form2.html, на которые есть ссылки в этом примере. Списки определений

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

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

Рис. 2.10. Применение вложенных списков

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

<A HREF="#BukvaV">B</A>

а в соответствующее место в словаре нужно не забыть поставить соответствующий якорь, например:

<A NAME="BukvaV">B</A>

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

<HR ALIGN="left" WIDTH="40%">

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

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

<SMALL><A HREF="#Top">B начало</А></SMALL>

Теперь обсудим, как организовать объяснение терминов. Для этого в HTML предусмотрен тег <DL> . Все, что находится между ним и его закрывающей парой </DL> , считается списком определений. Внутри этого списка возможно применение тегов <DT> для выделения самих терминов и <DD> для их определений. Теги <DT> и <DD> могут использоваться без соответствующей закрывающей пары (сравните с рассмотренным ранее тегом <LI> ). Элементы, обозначенные как термины ( <DT> ), выводятся практически без отступа, а элементы, обозначенные как определения ( <DD> ) — с довольно большим отступом. Ни те, ни другие элементы не маркируются.

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

Итак, приведем пример странички-словаря терминов. Для экономии места алфавит здесь обрывается на букве “Е”. Далее его легко можно продолжить самостоятельно (а если терминов много, то, возможно, стоит его продолжить в другом файле, чтобы не заставлять пользователя ждать загрузки слишком большого файла с сервера). Более того, здесь заполнены только разделы на буквы “А” и “Б”, чего для примера вполне достаточно.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">

<HTML>

<HEAD>

<TITLE>Словарь терминов</TITLE>

<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html;charset=windows-1251">

</HEAD>

<BODY
BGCOLOR="#EAEAEA" TEXT="Black"
LINK="#7A3F51" VLINK="#7A3F51"
ALINK="#7A3F51">

<H1><A NАМЕ="Тор">Словарь терминов</А></Н1>

<HR ALIGN="left" WIDTH="40%">

<BR>

<А HREF=="#BukvaA">A</A>

<А HREF="#BukvaB">Б</A>

<А HREF="#BukvaV">B</A> <А HREF="#BukvaG">Г</A>

<А HREF="#BukvaD">Д</A> <А HREF="#BukvaE">E</A> </НR>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaA">A</A></H> <DL>

<DT><A NAME="avtentich"><B>ABTEHTИЧECKИЙ КАДАНС</В></А>

<DD>кадансовый оборот, в котором заключительная тоническая гармония предваряется доминантовой

<DT><A NAME="aliquot"><B>AЛИKBOTHЫE СТРУНЫ</В></А>

<DD>резонирующие струны, к которым исполнитель не прикасается во время игры

<DT><A NAME="atakta"><B>ATAKTA</B></A>

<DD>гармоническйй элемент на басу нижнего или верхнего вводного тона

</DL>

<SMALL><A HREF="#Top">B начало</А></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaB">B</A></H1> <DL>

<DT><A NAME="bagatel"><B>БАГАТЕЛЬ</B></A>

<DD>небольшая нетрудная для исполнения пьеса

<DT><A NAME="bartok"><B>БAPTOKOBCKOE ПИЦЦИКАТО</В></А>

<DD>сильный щипок струны с последующим ударом струны о гриф

<DT><A NAME="bonang"><B>БOHAHГ</B></A>

<DD>Ha6op из 10-12 гонгов разного размера </DL>

<SMALL><A HREF="#Top">B начало</А></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaV">B</A></Hl>

<DL>

</DL>

<SMALL><A HREF=<"#Top">B начало</А></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1XA NAME=<"#BukvaG">Г</A></H1>

<DL>

</DL> <SMALL><A HREF="#Top">B начало</А></Small>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME=="#BukvaD">A</A></H1> <DL>

</DL>

<SMALL><A HREF="#Top">B начало</А></Small>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaE">E</A></Hl> <DL>

</DL>

</DL>

<SMALL><A HREF="#Top">B начало</А></Small>

</BODY>

</HTML>

Результат показан на рис. 2.11. Как видите, все достаточно строго и наглядно. Кстати, обратите внимание на то, что каждый термин мы также оформили как якорь. Это сделано для того, чтобы с других страниц нашего предполагаемого сайта можно было ссылаться непосредственно на объяснение этого термина. Например, если наш файл-словарь терминов называется glossary, html, то в каком-нибудь другом файле на этом сайте мы можем написать приблизительно следующее:

...характеризуется частым использованием

<А HREF="glossary.html #bartok">6apтоковскoгo пиццикато</А>, а

также приемов типа постукивания по декам и обечайке...

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

Рис. 2.11. Использование списка терминов

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

Если вы внимательно просмотрели последний листинг, то, вероятно, заметили еще одну строку, значение которой ранее не пояснялось:

<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1251">

Здесь применен тег < МЕТА> . Он может, вообще говоря, использоваться для ввода различной дополнительной информации: ключевых слов, описания

веб-страницы, указания ее автора, программы-генератора и т. п. Но в дан- ном случае этот тег используется для определения кодировки символов. Поскольку в тексте используются русские буквы, то есть, символы с ASCII-кодами, большими 128, необходимо указать, в какой кодировке эти символы нужно отображать. Если кто не совсем понял, о чем речь, тому можно это место пропустить, но лучше обратиться к соответствующей литературе. Большинство броузеров обычно это делают автоматически, и кроме того, имеют встроенную возможность выбора кодировки. Как правило она находится в меню View (Вид). Однако иногда бывает полезно указать кодировку в явном виде.

В данном случае мы имеем дело с файлом в кодировке Windows, поэтому в качестве значение свойства charset указано "windows-1251". Кстати, если вы работаете в другой кодировке, например, KOI8, вам следует ввести другое значение — "koi8-r", иначе эта страничка будет нечитаемой.

К сожалению, для явного указания кодировки приходится использовать столь длинный тег. Правда, многие броузеры сейчас начинают понимать и просто указание “без лишних слов”: <МЕТА CHARSET="windows-1251"> . Однако этот метод не универсален, поэтому для лучшей совместимости стоит всегда писать длинную строку, приведенную выше.


2.4

2.4. Создание таблиц

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

Рис. 2.1 2 . Таблица, созданная простейшими средствами HTML

Как же сделана эта таблица? Для того чтобы это понять, давайте рассмотрим сначала соответствующие средства HTML.

Формирование структуры таблицы

Любая таблица определяется в HTML с помощью тега <TABLE> . Все, что расположено между тегами <TABLE> и </TABLE> , считается таблицей. Однако не спешите! Если вы напишете что-нибудь вроде

<TABLE>

Это уже таблица?

</TABLE>

то, скорее всего, результат вас разочарует: броузер отобразит просто обычный текст. Дело в том, что мало создать таблицу, надо в ней еще создать хотя бы одну строку, а в строке хотя бы одну ячейку. Строки таблицы создаются с помощью тега <TR> и его закрывающего тега, а ячейки — с помощью тега <TD> и его закрывающего тега.

Однако, написав

<TABLE>

<TR>

<TD> Это уже таблица?

</TD>

</TR>

</TABLE>

мы получим тот же результат, что и раньше (по крайней мере, в большинстве броузеров). В чем же дело? А дело в том, что по умолчанию таблицы обычно отображаются без рамки. Если мы хотим, чтобы наша таблица из одной ячейки имела рамку, мы должны явно задать ее ширину, установив атрибут BORDER=, например, вот так:

<TABLE BORDER="3"> <TR>

<TD> Это уже таблица! </TD> </TR> </TABLE>

Вот теперь это уже на что-то похоже (рис. 2.1 3 ). Кстати, довольно интересно рассмотреть рамку, установив что-нибудь вроде BORDER="30".

Основные атрибуты таблицы

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

таблицы. Например, если мы напишем <TABLE WIDTH="50" BORDER="3">,

Рис. 2.1 3 . Таблица из одной ячейки

то броузер отобразит таблицу шириной в 50 пикселов. При этом во фразе Это уже таблица! последнее слово, скорее всего, не поместится в длину таблицы и автоматически перенесется на другую строку. А если установить

WIDTH-50%, то таблица растянется на половину ширины окна броузеоа (рис. 2.1 4).

Рис. 2.1 4 . Установка ширины таблицы

А что делать, чтобы текст не “прилеплялся” так сильно к границе ячейки как показано на рис. 2.14 и 2.15? Для этого тоже существует специальный атрибут — CELLPADDING=. Его значение определяет, на сколько точек текст будет отступать от края ячейки. Для лучшей иллюстрации этого атрибута выберем в качестве его значения какое-нибудь большое число например,20:

<TABLE WIDTH="50%" BORDER="3" CELLPADDING="20"> <TR>

<TD> Это уже таблица! </TD> </TR>

</TABLE>

Результат показан на рис. 2.1 5 . Разумеется, в обычных ситуациях величину CELLPADDING= устанавливают приблизительно равной 3-5 точек, чтобы просто немного отступить от края ячейки.

Рис. 2.1 5. Применение атрибута CELLPADDING=

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

<TABLE WIDTH="50%" BORDER="6" CELLSPACING="6" CELLPADDING="20"> <TR>

<TD> Это уже таблица! </TD> </TR> </TABLE>

Результат представлен на рис. 2.1 6.

Рис. 2.1 6 . Применение атрибута CELLSPACING=

Кстати, рамка таблицы совершенно не обязана быть серой, по крайней мере в броузере Internet Explorer (версии 3 и выше). Для этого служит атрибут BORDERCOLOR=, которому можно дать в качестве значения любой доступный цвет. Однако, если вставить в наш пример что-нибудь вроде BORDERCOLOR="green" и сравнить результат с предыдущим, то он, скорее всего, вам не понравится: в предыдущем случае табличная рамка слева и сверху выводилась более светлым оттенком, чем снизу и справа, за счет чего возникало впечатление “выпуклости”. А теперь вся рамка стала одноцветной — зеленой — и смотрится гораздо “скучнее”. То же справедливо и для рамки ячейки (которая была, наоборот, “вогнутой”).

Поэтому вместо одного атрибута BORDERCOLOR= мы рекомендуем употреблять два: BORDERCOLORLIGHT= и BORDERCOLORDARK=, задающие цвет, соответственно, светлой и темной сторон рамки. Правда, эти атрибуты поддерживаются только броузером Internet Explorer.

<TABLE
WIDTH="50%" BORDER=="6"
CELLSPACING="6" CELLPADDING="20"
BORDERCOLORLIGHT="lime"
BORDERCOLORDARK="green">

<TR>

<TD> Это уже таблица! </TD>

</TR>

</TABLE>

Результат показан на рис. 2.17. Кстати, при просмотре на экране компьютера обратите внимание на то, что lime и green — в принципе подходящее, но не самое лучшее сочетание значений данных атрибутов. Для придания естественности табличной рамке полезно немного поэкспериментировать с оттенками цветов.

Рис. 2.1 7 . Окрашивание рамки таблицы

Цвет фона таблицы можно задать с помощью атрибута BGCOLOR=. Он может отличаться от цвета общего фона всей страницы, определенного атрибутом BGCOLOR= тега <BODY>.

Чтобы выровнять таблицу по центру или правому краю, можно установить в теге <TABLE> атрибут ALIGN=. Все это мы сейчас проиллюстрируем, а заодно.давайте добавим еще одну ячейку в нашу таблицу:

<TABLE
WIDTH="50%" BORDER="6"
CELLSPACING="6" CELLPADDING="20"
ALIGN="center" BORDERCOLORLIGHT="Lime"
BORDERCOLORDARK="Green" BGCOLOR="#DFFFDF">

<TR>

<ТD>Это первая ячейка</ТD>

<ТD>Это вторая ячейка</ТD> </TR>

</TABLE>

Результат представлен на рис. 2.1 8 . Как видите, расстояние между ячейками сохраняется равным значению атрибута CELLSPACING= теперь это заметно особенно хорошо.

Рис. 2.1 8 . Таблица из двух ячеек Теперь добавим в нашу таблицу вторую строку:

<TABLE
WIDTH="50%" BORDER="6"
CELLSPACING="6" CELLPADDING="20"
ALIGN=="center" BORDERCOLORLIGHT="Lime"
BORDERCOLORDARK="Green" BGCOLOR="#DFFFDF">

<TR>

<ТD>Это первая ячейка</ТD>

<TD>Это вторая ячейка</ТD> </TR>

<TR>

<ТD>Это первая ячейка второй строки</ТD>

</TR>

</TABLE>

Поскольку во второй строке всего одна ячейка (см. рис. 2. 19 ), на месте отсутствующей второй ячейки второй строки осталось пустое пространство.

Иногда это бывает полезно, но чаще требуется оставить пустую рамку незаполненной ячейки. Как это сделать? Если мы просто добавим в таблицу пару тегов <TD> </TD>, то, как ни странно, ничего не изменится — вокруг пустой ячейки рамка не отображается! Добавление пробела между тегами ячейки также ничего не дает, поскольку в HTML лишние пробелы игнорируются...

Рис. 2. 19 . Пример таблицы с “недостающей” ячейкой

Рис. 2.2 0 . Пример таблицы с пустой ячейкой

До сих пор мы рассматривали только атрибуты тега <TABLE> . Однако теги <TR> и <TD> тоже могут иметь собственные атрибуты, такие, как BGCOLOR=, BORDERCOLOR=, BORDERCOLORLIGHT=, BORDERCOLORDARK= и ALIGN=. Их значения распространяются только на одну строку или ячейку таблицы. Кроме того, имеется атрибут VALIGN=, с помощью которого можно управлять вертикальным выравниванием текста строки или ячейки. Этот атрибут может принимать значения top (выровнять по верхнему краю), middle (по середине) и bottom (по нижнему краю). Кроме того, в некоторых броузерах, например Opera, поддерживается также атрибут NOWRAP, запрещающий перенос текста ячейки на следующую строку.

Управление шириной столбцов

Если вы посмотрите на рис. 2.2 0 , то увидите, что ширина столбцов в нашей таблице разная. Это происходит потому, что броузер распределяет место в таблице в зависимости от количества текста, которого в первом столбце оказалось больше. Однако, если в теге первой ячейки указать <TD WIDTH="50%"> , то оба столбца станут равными по ширине. Таким образом, можно пользоваться атрибутом WIDTH= в теге <TD> так же, как и в теге <TABLE> , определяя ширину каждой ячейки либо в пикселах, либо в процентах от общей ширины окна броузера. Правда, строго говоря, нельзя задать ширину каждой ячейки, а лишь ширину каждого столбца, поскольку в большинстве броузеров все ячейки в столбце всегда имеют одинаковую ширину.

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

Объединение ячеек

Иногда в таблицах встречаются так называемые объединенные ячейки — когда несколько расположенных рядом ячеек сливаются в одну большую. Это можно сделать, установив атрибуты COLSPAN= (для объединения соседних столбцов) или ROWSPAN= (для объединения соседних строк):

<TABLE
WIDTH="50%" BORDER="6"
CELLSPACING="6" CELLPADDING="20"
ALIGN="center" BORDERCOLORLIGHT="Lime"
BORDERCOLORDARK="Green" BGCOLOR="#DFFFDF">

<TR>

<TD WIDTH="33%">Этo первая ячейка</ТD>

<TD WIDTH="33%">Это вторая ячейка</ТD>

<TD ROWSPAN="3">A это три ячейки третьего столбца объединились в одну большую ячейку</ТD>

</TR> <TR>

<TD COLSPAN="2">Это единственная ячейка второй строки, объединяющая оба столбца</ТD>

</TR>

<TR>

<TD>3ro первая ячейка третьей строки</ТD>

<TD>A это вторая ячейка третьей строки</ТD> </TR>

</TABLE>

Результат показан на рис. 2.21. Здесь, как видите, отображена таблица из трех строк по три ячейки. Однако третья ячейка первой строки с помощью атрибута ROWSPAN="3" объединена с остальными двумя ячейками третьего столбца. Поэтому в следующих строках мы можем спокойно забыть про третий столбец — место уже занято. Поэтому в третьей строке таблицы всего две ячейки. А во второй строке происходит следующее: мы с помощью атрибута COLSPAN="2" объединяем две оставшиеся ячейки этого ряда в одну.

Кстати, обратите внимание на то, что, хотя ширина первых двух столбцов таблицы задана равной 33%, то есть примерно треть ширины таблицы приходится на каждый столбец, правый столбец на самом деле занимает явно больше места. Это произошло потому, что иначе броузеру не удалось бы уместить в ширину этого столбца длинное слово “объединились”. В результате броузер самостоятельно чуть расширил этот столбец за счет двух остальных.

Мы с вами еще не рассмотрели такие элементы таблицы, как заголовок и заключение. В HTML 4.0 можно все основное содержание таблицы обозначить тегом <TBODY> . Тогда заголовок таблицы обозначается тегом <THEAD> , а заключение — тегом <TFOOT> . Все три тега употребляются с

Рис. 2.21. Пример объединения ячеек таблицы

закрывающими тегами и могут иметь различные атрибуты, например BGCOLOR=, ALIGN=, VALIGN=.

А для ячеек заголовка таблицы вместо тега <TD> обычно используют тег <ТН> . В принципе, это одно и то же, однако в ячейках <ТН> текст по умолчанию выравнивается по центру и отображается полужирным начертанием шрифта.

Для примера добавим в нашу учебную таблицу заголовок и заключение:

<TABLE
WIDTH="50%" BORDER="6"
CELLSPACING="6" CELLPADDING="20"
ALIGN="center" BORDERCOLORLIGHT="Lime"
BORDERCOLORDARK="Green" BGCOLOR="#DFFFDF">

<THEAD BGCOLOR="Aqua">

<TR><TH COLРАN="3">УЧЕБНАЯ ТАБЛИЦА</ТН></ТR> </THEAD>

<TBODY>

<TR>

<TD WIDTH="33%"> первая ячейка</ТD>

<TD WIDTH="33%"> вторая ячейка</ТD>

<TD ROWSPAN="3">A это три ячейки третьего столбца объединились в одну большую</ТD>

</TR>

<TR>

строки

<TR COLSPAN="2">единственная ячейка второй строки, объединяющая оба столбца</ТD>

</TR>

<TR>

<ТD>Это первая ячейка третьей строки</ТD>

<TD>A это вторая ячейка третьей строки</ТD>

</TR>

</TBODY> <TFOOT BGCOLOR="Yellow">

<TR><TD COLSPAN="3" ALIGN="center"SMALL >Понравилось делать?</Small></ТD>

</ТR> ><Small>Понравилось таблицы</TFOOT>

</TABLE>

Рис. 2.22. Использование заголовка

Результат показан на рис. 2.22. Осталось добавить, что использование обсуждавшегося выше атрибута RULES= со значением "groups" подразумевает именно эти “группы”: заголовок, основное содержание и заключение таблицы, обозначенные тегами <THEAD>, <TBODY> и <TFOOT>.

Анализ примера

Теперь, вооружившись полученными знаниями, давайте вернемся к таблице, представленной на рис. 2.13 и посмотрим, как же она сделана. В качестве основного цвета таблицы здесь выбран серебристый (#Е4Е4Е4), Атрибут WIDTH="100%" растягивает ее на всю ширину окна броузера, а значение CELLSPACING="0" “прижимает” ячейки друг к другу. С помощью значения CELLPADDING="2" обеспечивается наличие небольших “полей” в каждой ячейке.

В первой строке таблицы задается ширина столбцов. Ширина первого столбца с номерами хоккейных команд задана равной 20 пикселам, а всех столбцов с результатами матчей — 40 пикселам. Ширина столбца с названиями команд задана равной 20% от ширины окна. Ширина двух последних столбцов не задана вообще — им отводится все оставшееся место.

Во многих ячейках таблицы задан атрибут ALIGN="center", без которого выравнивание текста происходило бы по левому краю. Во всех ячейках с результатами встреч задан белый фон (BGCOLOR="white"), в ячейках с количеством очков и заброшенных/пропущенных шайб для лучшего визуального выделения использован другой цвет фона. Количество очков, как главная информация в каждой строке таблицы, выделено просто полужирным и чуть увеличенным шрифтом (с помощью тегов <В> и <ВЮ>). Для лучшего “разнесения” в разные стороны количества заброшенных и пропущенных шайб между ними использовано длинное тире — это специальный символ &mdash;.

Зачерненные квадраты турнирной таблицы сделаны просто — с помощью ячеек с черным цветом фона (BGCOLOR="black")“ И, наконец, для отобра-I жения рамки вокруг пустой ячейки (левой верхней) туда был помещен неразрывный пробел (&nbsp;).

Теперь давайте посмотрим на текст этой странички целиком:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD>

<TITLE>TypHMpHan таблица</Тitle>

</HEAD>

<BODY
BGCOLOR="#FFFFB3" TEXT="02020"
LINK="400080" VLINK="#400080"
ALINK="H00080">

<DIV ALIGN="center"

<Н1>ЧЕМПИОНАТ ГОРОДА ПО ХОККЕЮ</Н1>

<НЗ>ТАБЛИЦА РЕЗУЛЬТАТОВ</НЗ>

</DIV>

<TABLE
ALIGN="center" BGCOLOR="#E4E4E4"
WIDTH="100%" CELLSPACING="0"
CELLPADDING="2" BORDER="3"> <TR>

<TD WIDTH="20" ALIGN="center">&nbsp;</TD>

<TD WIDTH="20%">Koмaндa</TD>

<TD WIDTH=Э40" ALIGN=Эcenter">1</TD>

<TD WIDTH="40" ALIGN="center">2</TD>

<TD WIDTH="40" ALIGN="center">3</TD>

<TD WIDTH="40" ALIGN="center">4</TD>

<TD WIDTH="40" ALIGN="center">5</TD>

<TD WIDTH="40" ALIGN="center">6</TD>

<TD ALIGN="center">Шайбы</TD>

<TD ALIGN="center">Очки</TD> </TR>

<TR>

<TD

ALIGN="center">1</TD>

<TD>&laquo;POTOP&raquo;</TD>

<TD

BGCOLOR="black"></TD> <TD

ALIGN="center"

BGCOLOR="white">6:4</TD> <TD

ALIGN="center"

BGCOLOR="white">2:3</TD> <TD

ALIGN="center"

BGCOLOR="white">7:3</TD> <TD

ALIGN="center"

BGCOLOR="white">2:1</TD> <TD

ALIGN="center"

BGCOLOR="white">0:0</TD> <TD

ALIGN="center"

BGCOLOR="#DFFFDF">17&mdash;11</TD>

<TD ALIGN="center" BGCOLOR="#FF8484"><B><BIG>7</BIG>

</TR> <TR>

<TD ALIGN=”center”2</TD>

<TD>&laquo;POTATOP&raquo;</TD>

<TD ALIGN=”center” BGCOLOR=”white>”4:6</TD>

<TD BGCOLOR=”black”></TD>

<TD ALIGN="center" BGCOLOR="white"5: 4</TD>

<TD ALIGN="center" BGCOLOR="white">5:3</TD>

<TD ALIGN="center" BGCOLOR="white">5:5</TD>

<TD ALIGN="center" BGCOLOR="white">2:2</TD>

<TD ALIGN="center" BGCOLOR="#DFFFDF">21&mdash;20</TD>

<TD ALIGN="center" BGCOLOR="#FF8484"><B><BIG>6</BIG> </B></TD>

</TR>

<TR>

<TD ALIGN="center">3</TD>

<ТD>&lаquo;УРОЖАЙ&raquo;</ТD>

<TD ALIGN="center" BGCOLOR="white">3:2</TD>

<TD ALIGN="center" BGCOLOR="white">4:5</TD>

<TD BGCOLOR="black"></TD>

<TD ALIGN="center" BGCOLOR="white">1:1</TD>

<TD ALIGN="center" BGCOLOR="white">11:2</TD>

<TD ALIGN="center" BGCOLOR="white">14:4</TD>

<TD ALIGN="center" BGCOLOR="#DFFFDF">33&mdash;14</TD>

<TD ALIGN="center" BGCOLOR="#FF8484"><B><BIG>5</BIG> </B></TD>

</TR>

<TR>

<TD ALIGN="center">4</TD>

<TD>&laquo;МЕЧТА&raquo;</TD>

<TD ALIGN="center" BGCOLOR="white">3:7</TD>

<TD ALIGN="center" BGCOLOR=="white">3 ; 5</TD>

<TD ALIGN="center" BGCOLOR="white">l:1</TD>

<TD BGCOLOR="black"></TD>

<TD ALIGN="center" BGCOLOR="white">l:1</TD>

<TD ALIGN="center" BGCOLOR="white"> 10 : 0</TD>

<TD ALIGN="center" BGCOLOR="#DFFFDF">18&mdash;14</TD>

<TD ALIGN="center" BGCOLOR="#FF8484"><B><BIG>4</BIG> </B></TD>

</TR>

<TR>

<TD ALIGN="center">5</TD>

<TD>&laquo;МЕЧТА& raquo;</TD>

<TD ALIGN="center" BGCOLOR="white">l:2</TD>

<TD ALIGN="center" BGCOLOR="white">5:5</TD>

<TD ALIGN="center" BGCOLOR="white">2:11</TD>

<TD ALI.GN="center" BGCOLOR="white">l: 1</TD>

<TD BGCOLOR="black"></TD>

<TD ALIGN="center" BGCOLOR="white">8:3</TD>

<TD ALING="'center"BGCOLOR="#DFFFDF">17&mdash;22</TD>

<TD ALIGN="center" BGCOLOR="#FF8484"><B><BIG>4</BIG> </B></TD>

</TR>

<TR>

<TD ALIGN="center">6</TD>

<TD>&laquo;OKA3ИЯ&raquo;</TD>

<TD ALIGN="center" BGCOLOR="white">0:0</TD>

<TD ALIGN="center" BGCOLOR="white">2:2</TD>

<TD ALIGN="center" BGCOLOR="white">4:14</TD>

<TD ALIGN="center" BGCOLOR="white">0 :10</TD>

<TD ALIGN="center" BGCOLOR="white">3 : 8</TD>

<TD BGCOLOR="black"></TD>

<TD ALIGN="center" BGCOLOR="#DFFFDF">9&mdash;34</TD>

<TD ALIGN="center" BGCOLOR="#FF8484"><B><BIG>2</BIG> </B></TD>

</TR>

</TABLE>

</BODY>

</HTML>

Как видите, здесь использованы далеко не все возможности HTML-таблиц а результат, тем не менее, вполне приемлемый.

Разумеется, только что рассмотренная таблица является “статичной”: при изменении, например, одного из результатов матчей нам придется вновь вручную подсчитывать шайбы и очки. Интересно сделать таблицу, которая могла бы это делать сама. Например, изначально будучи вообще пустой, она могла бы реагировать на постепенное внесение результатов матчей.


3

3. Графика на веб-странице

3.1. Основные способы применения графики

В предыдущей главе мы рассмотрели несколько примеров создания веб-страниц. Вы, очевидно, уже обратили внимание, что все они смотрятся довольно “строго”. А все дело в том, что в них не использовались графические элементы. Сейчас, вообще говоря, в Интернете осталось не так много страниц без графических элементов, поскольку с помощью графики можно не только проиллюстрировать предлагаемый материал, но и немного “оживить” общее оформление, о чем речь пойдет в этой главе.

Фоновое изображение

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

Допустим, что у нас заготовлен соответствующий фоно вый рисунок (о том, как это сделать, см. в разделе 3.5) — он записан в файле под именем back1 .jpg (рис. 3.1). Если при отдельном просмотре этого рисунка он вам нравится, это еще ничего не значит. Чтобы определить, подходит ли рисунок в качестве фона к тексту, его нужно проверить “в деле”.

Чтобы поместить рисунок на веб-страницу в качестве фона, нужно установить в теге <BODY> атрибут BACKGROUND= со значением, содержащим имя файла рисунка.

<BODY BACKGROUND""Images/back1.jpg">

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

Рис. 3.1. Фоновый рисунок

Можно указать либо относительное местоположение файла рисунка (то есть путь доступа к нему относительно расположение исходного HTML-файла), либо его полный URL-адрес. Здесь и далее мы предполагаем, что вы разместили в той же папке, что и HTML-файл, папку \lmages, в которую складываете все графические файлы.

Вернемся к нашему рисунку. Ясно, что на таком сероватом фоне черные буквы будут читаться плохо, поэтому сразу определим для текста белый цвет (или почти белый). Гиперссылок у нас пока нет, но о них все равно надо позаботиться заранее. Пока давайте определим для них желтый цвет. Посмотрим, что у нас получается:

<HTML>

<HEAD>

<TITLE>Клавинова</TITLE>

</HEAD>

<BODY
BACKGROUND="3.1.jpg" TEXT="#F8F8F8"
LINK="Yellow" VLINK="Yellow"
ALINK="Yellow">

<H1><DIV ALIGN="center">Клавинова</DIV></H1>

<P ALIGN="justify">

Инструменты серии

<BIG>Клавинова</BIG>

, выпускаемые компанией Yamaha, являются достойной заменой

<I>обычных</I>

пианино для массового пользователя. Во-первых,

<BIG>KJIABHHOBA</BIG>

стоит

<В>дешевле</В>

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

<U>лучше</U>

, чем на &laquo;живых&raquo; инструментах того же (или даже чуть более

<SUP>высокого</SUP>)

ценового диапазона.

</Р> </BODY> </HTML>

Результат показан на рис. 3.2. Кстати, обратите внимание, что здесь мы немного “поработали” с элементами текста, чтобы чуть-чуть оживить их: название “клавинова” выделено крупным шрифтом, достоинства — где подчеркнуты, где выделены полужирным шрифтом, слово “обычных” для подчеркивания иронии выделено курсивом, а слово “высокого” поднято над основным текстом с помощью тега <SUP>.

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

Рис. 3.2. Не самое удачное применение фонового рисунка

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

Кроме того, согласно общему правилу, светлый текст на темном фоне лучше всегда делать немного крупнее. Поэтому заключим наш текст в теги <BIG>...</BIG>.

Графические иллюстрации

И, наконец, проиллюстрируем наш текст, вставив перед описанием фотографию клавиновы. Предположим, что фотография у нас уже готова и лежит в палке \lmages под именем clavi.gif. Вставить ее в текст можно с помо щью тега <IMG> , например, вот так:

<IMG SRC="Images/clavi.gif">

В принципе, этого уже достаточно — на месте этой записи броузер отобразит нашу картинку. Однако лучше указать в теге <IMG> еще несколько атрибутов.

Во-первых, надо помнить, что картинки загружаются из сети всегда намного медленнее, чем обычный текст. Это я говорю не к тому, что сам файл картинки должен быть не очень большого объема (это верно, но этот вопрос мы обсудим отдельно), а к тому, что при такой записи, как выше, многие броузеры, начав загружать картинку, приостановят загрузку последующего текста до тех пор, пока картинка не будет загружена полностью. Но для читателя было бы удобнее, если бы текст продолжал загружаться араллельно с картинкой: пока она догружается, можно было бы что-то уже читать. Чтобы броузер мог это сделать, ему нужно явно указать размеры будущей картинки с помощью атрибутов WIDTH= и HEIGHT=:

<IMG SRC="Images/clavi.gif" WIDTH="300" HEIGHT="200">

Вообще говоря, с помощью этих атрибутов можно задать какие угодно размеры картинки, “растянув” или сжав ее как душе угодно. Однако обычно этого не делают, и вот почему. Представлять картинку меньшей, чем она есть, нецелесообразно, поскольку зачем тогда грузить большой файл? Ведь файлы для картинок большого размера имеют большой размер и грузятся из Интернета, соответственно, намного дольше. Лучше уж сделать малень кий файл для картинки маленького размера и быстро загрузить его. А если представить картинку большей, чем она есть, то, как правило, она будет выглядеть малопривлекательно за счет появления “ступенчатости” как в формах, так и в цвете.

Далее, хорошим тоном является наличие так называемого альтернативного текста для тех случаев, когда в броузере отключен просмотр графики. Тогда на месте нашей картинки будет выведен прямоугольник соответ ствующего размера, который сопровождается пояснением, что за картинка на этом месте должна быть. Альтернативный текст вводится как значение атрибута ALT:

<IMG SRC="Images/clavi.gif" WIDTH="300" HEIGHT="200" АLТ="Клавинова">

Наконец, вокруг рисунка можно отобразить рамку. Толщина этой рамки задается как значение атрибута BORDER=. Если мы, как в данном случае, не хотим отображать рамку вокруг рисунка, то можем ничего и не указывать, так как большинство броузеров по умолчанию рамку не рисуют. Но некоторые броузеры все же это делают, и “для верности” неплохо бы указать и отсутствие рамки тоже:

<IMG
SRC="Images/clavi.gif" WIDTH="300"
HEIGHT="200" АLТ="Клавинова"
BORDER="0">

Чего еще не хватает нашему HTML-файлу? Конечно же, гиперссылок! Без них любой документ в Интернете воспринимается гораздо скучнее, поскольку посетитель сразу видит, что зашел в тупик. Поэтому обязательно добавляйте гиперссылки везде, где это только можно. В данном случае, например, слово “Yamaha” просто просится стать гиперссылкой на сайт соответствующей компании. Сделаем это:

<A HREF="http://www.yamaha.com">Yamaha</A>

Кстати, картинки тоже могут содержать гиперссылки. Мы можем, напри мер, точно так же, как со словом “Yamaha”, поступить и с нашим тегом картинки. Тогда щелчок на изображении клавиновы также уведет пользователя на сайт компании Yamaha.

Давайте посмотрим, что у нас получается.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>KJIABHHOBA</TITLE>

</HEAD>

<BODY
BACKGROUND="Images/back4.jpg" TEXT="#F8F8F8"
LINK="Yellow" VLlNK="Yellow"
ALINK="Yellow" BGCOLOR="#OBOBOB">

<H1><DIV ALIGN="center">KJIABHHOBA</DIV></Hl>

<DIV ALIGN="center">

<A HREF="http://www.yamaha.com">

<IMG
SRC="Images/clavi.gif" WIDTH="300"
HEIGHT="200" ALT="KJIABHHOBA"
BORDER="0"></A></DIV>

<BIG>

<P ALIGN="justify">Инструменты серии

<BIG>KJIABMHOBA</BIG>

, выпускаемые компанией

<А HREF="http: //www.yamaha.com">Yamaha </A>

, являются достойной заменой

<I>обычных</I>

пианино для массового пользователя. Во-первых,

<ВIG>КЛАВИНОВА</ВIG>

стоит

<В>дешевле</В>

мало-мальски хорошего пианино или тем более рояля, а во-вторых, ее звук и исполнительские ощущения зачастую не хуже, а <U>лучше</U>, чем на &lаquо;живых&raquo; инструментах того же (или даже чуть более

<SUP>Bыcoкoro</SUP>

) ценового диапазона.

</Р>

</BIG>

</BODY>

</HTML>

Результат наших трудов представлен на рис. 3.3. Обратите внимание на то, что для расположения картинки по центру мы поступили так же, как и при центрировании обычного текста — использовали конструкцию <DIV ALIGN="center">.

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

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

Рис. 3.3. Пример странички с фоновым рисунком и иллюстрацией

видно! Да и вообще, фоновый рисунок может загрузиться и прорисоваться нe сразу, ведь это графический файл, имеющий гораздо большие размеры, чем текст! Поэтому всегда нелишне явно указать нужный цвет фона, желательно близкий по оттенку к фоновому рисунку.

Кстати, тег <IMG> может иметь собственный атрибут ALIGN=, который управляет расположением рисунка относительно текста. В нашем примере это было не актуально, поскольку рисунок находился в отдельном блоке <DIV> . Но если рисунок “встроен” в текст, то есть несколько вариантов его расположения:

ALIGN="left" — текст обтекает рисунок, который располагается слева;

ALIGN="right" — текст обтекает рисунок, который располагается справа;

ALIGN="top" — рисунок располагается внутри текстовой строки, и его верхняя граница совпадает с верхней границей букв текста (можно также применять значение "texttop");

ALIGN="middle" — рисунок располагается внутри текстовой строки, которая вертикально выравнивается по центру рисунка (можно также при менять значение "absmiddle");

ALIGN="bottom" — рисунок располагается внутри текстовой строки, и его нижняя граница совпадает с нижней границей букв текста (можно также применять значение "absbottom" или "baseline").

Кроме того, чтобы рисунок не слишком “прижимался” к тексту, можно оставить между ними немного “воздуха”. Для этого в теге <IMG> используют атрибуты HSPACE= и VSРАСЕ=, значения которых задают соответственно горизонтальное и вертикальное “поля” рисунка.

И еще небольшое замечание: броузер Internet Explorer (версия 4 и выше) позволяет с помощью тега <IMG> загружать и просматривать также видеофрагменты в формате AVI (Video for Windows). Для этого можно установить атрибут DYNSRC=, в качестве значения которого указать имя AVT-файла. При этом можно дополнительно указать в атрибуте START=, когда следует начинать проигрывание видео: "FILEOPEN" — сразу после загрузки файла или "MOUSEOVER" — после наведения указателя мыши на изображение. Атрибут LOOP= позволяет установить количество проигрываний: "О" означает бесконечное повторение, алюбое другое число указывает точное количество повторов.


3.2

3.2. Графические форматы Интернета

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

Несмотря на то что графических форматов очень много, в качестве стандартных для использования в Интернете приняты только три из них. Это CompuServe Graphic Interchange Format, или, попросту, GIF, формат JPEG (названный по имени группы создателей — Joint Picture Expert Group) и сравнительно новый формат PNG (Portable Network Graphics). Кроме того, на скорую стандартизацию претендуют форматы DjVu (этот формат оптимизирован для представления документов, содержащих одновременно текст и графику) и LuRaTech Wavelet (LWF) — формат, отличающийся возможностью высокой степени сжатия при довольно высоком качестве. Он отличается тем, что при сжатии можно заранее установить размер будущего файла.

Однако пока создателю веб-страниц лучше ориентироваться лишь на два наиболее распространенных в Интернете формата — GIF и JPEG. Они поддерживаются всеми броузерами и не требуют каких-либо дополнительных модулей для отображения.

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

Формат GIF

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

Рис. 3.6. Страничка с круглой фотографией

Во-первых, GIF-рисунок может быть “прозрачным”. То есть, можно один цвет удалить из палитры GIF, определив его как прозрачный. Тогда при отображении, сквозь точки, окрашенные в этот цвет, на рисунке будет виден фон веб-страницы. Это очень помогает при создании рисунков фигурной формы. Например, этим приемом можно поместить на веб-страницу круглую фотографию. На самом-то деле она, конечно, прямоугольная, просто края ее сделаны прозрачными (рис. 3.6).

Исходный текст этой странички самый простой:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">

<HTML>

<HEAD>

<TITLE>Круглая фотография</ТITLE>

</НЕАD>

<BODY
BACKGROUND="' Images/back3.jpg"
BGCOLOR="#000000" TEXT="#FFFFFF"
LINK="Yellow" VLINK="Yellow"
ALINK="Yellow">

<DIV ALIGN="center">

<FONT SIZE="+3">HA ЭТУ СТРАНИЧКУ ПОМЕЩЕНА </FONT>

<BR>

<IMG
SRC="Images/yooiee2.gif" WIDTH="480"

HEIGHT="400"

BORDER="0"
ALT="ФОТОГРАФИЯ"<BR>

<FONT SIZE="+3">КРУГЛАЯ ФОТОГРАФИЯ! </FONT>

</DIV>

</BODY>

</HTML>

Однако дело здесь не в HTML-коде, а в GIF-файле. Цвет в его углах объявлен как прозрачный, и в результате мы можем видеть “сквозь него” фон странички, так что создается впечатление, фотография действительно круглая. Этим приемом иногда оживляют “прямоугольный” мир компьютерных окон...

Другое достоинство GIF-рисунков — возможность загружать их чересстрочным методом. Если графический файл имеет большой размер и грузится из Интернета долго, пользователь увидит сначала как бы нечеткие контуры будущего рисунка, а по мере загрузки изображение будет постепенно “проявляться”, что достигается очень простым приемом — изменением порядка загрузки строк изображения. Для этого необходимо при сохранении GIF-файла не забыть включить режим Interlaced (Чересстрочный).

И, наконец, еще одно достоинство GIF-файлов — они могут содержать не только статичные рисунки, но и целые анимационные фрагменты! На самом деле эти фрагменты представляют собой последовательности нескольких статичных кадров, а также информацию о том, сколько времени каждый кадр должен задерживаться на экране. Для создания подобных анимаций существуют специальные программы, например WWW Gif Animator (рис. 3.7). В такую программу можно загрузить несколько графических файлов подряд, а также использовать некоторые встроенные эффекты. Однако помните, что каждый лишний кадр ведет к увеличению размера файла, и если сделать анимированный GIF-файл, например из 500 кадров, очень мало кто сможет дождаться окончания его загрузки.

Рис. 3.7. Общий вид программы WWW Gif Animator

Формат JPEG

Теперь несколько слов о другом распространенном графическом формате — JPEG (файлы этого формата могут иметь расширение как .jpeg, так и .jpg). В отличие от GIF, этот формат предназначен для изображений типа фотографий. Файлы этого формата не ограничены палитрой из 256 цветов, при желании они могут содержать до 16 777 216 (то есть 2 24 ) цветов.

При сохранении JPEG-файла любая графическая программа указать степень сжатия, которую обычно измеряют в некоторых условных единицах от 1 до 100 (иногда от 1 до 10). При этом большее число соответствует меньшей степени сжатия, но лучшему качеству. И здесь важно найти хороший баланс. В большинстве случаев сжатие порядка 30-40% дает вполне качественный результат.

Итак, старайтесь во всех случаях обходиться этими двумя форматами. Если же возникла ужасная необходимость воспользоваться каким-либо другим форматом, потрудитесь выяснить, какие броузеры способны его отображать и какие дополнительные модули для этого нужны. Сообщите об этом на своей страничке рядом с файлом “экзотического” формата и поставьте гиперссылки на сайты, откуда можно эти дополнительные средства загрузить. А еще лучше будет, если в качестве альтернативного варианта поместите также изображение в формате GIF или JPEG


3.3

3.3. Графические элементы оформления веб-страниц

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

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

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

Конечно, можно многого достичь, используя стилевое оформление страницы (с помощью каскадных таблиц стилей, описанных в следующей главе). Однако есть еще один способ “оживить” веб-страницу. Он заключается в использовании небольшого числа мелких графических элементов в качестве элементов оформления. Обратите внимание на то, что эти элементы должны быть мелкими. Это важно по двум причинам: во-первых, они не отвлекают на себя внимание читателя (а только придают веб-странице лучший внешний вид), а во-вторых, малые по размеру рисунки загружаются из Сети довольно быстро, что обычно сопоставимо со скоростью загрузки текста.

Линейки и буквицы

Какие же графические элементы возможно применять в качестве такого “украшения”? Здесь надо проявить фантазию. Если вы придумаете что-нибудь оригинальное, ваша веб-страница будет смотреться необычно, “не как другие”, и запомнится посетителю. Однако перечислим несколько ставших уже традиционными вариантов такого применения графики. Во-первых, это различные графические разделители, обычно горизонтальные, применяемые вместо горизонтальной черты (<HR>). Хотя тег <HR> и поддается настройке, графический разделитель часто выглядит лучше.

Применение графических элементов оформления — различные кнопки и маркеры списков. О них специально пойдет речь в следующем разделе.

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

<IMG SRC="Images/bukvical.gif" WIDTH="121" HEIGHT="111" BORDER="0"'ALIGN="LEFT" АLТ="Д"> авным-давно жил-был на белом свете царь Горох. И были у него поля гороховые, и леса гороховые, и...

Для экономии места мы не приводим текст странички целиком, а только то место где вставлена буквица.) Установка атрибута ALIGN="left" обеспечивает обтекание текстом рисунка (буквицы). На всякий случай в качестве альтернативного текста дается буква “Д”, чтобы пользователю с отключенной графикой не приходилось строить догадки относительно первой буквы.

Для завершения оформления можно еще создать градиентный фон . Не забывайте только обязательно указывать значение атрибута ALT= во всех тегах <IMG>.

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


3.4

3.4. Графические маркеры

Итак, в предыдущем разделе мы упомянули о возможности создания графических маркеров списков. Она настолько привлекла создателей веб-страниц, что для их удобства были созданы специальные средства. Действительно, одно дело, когда маркерами списка являются стандартные кружочки или квадратики, и совсем другое — когда каждый сам имеет возможность создать маркер! Маркером может быть все что у годно — от просто цветных и немного выпуклых кружков и квадратов до изощренных миниатюрных художественных работ. Однако обратите внимание на то, что именно миниатюрных', маркеры списков должны по размеру как-то соответствовать высоте текстовой строки, и забота об этом ложится на автора еще на этапе создания изображения. Старайтесь создавать подобные изображения сразу в “натуральную величину”. Если создавать сначала крупные рисунки, а потом просто уменьшать их, то при уменьшении они могут стать неузнаваемыми! Все дело в том, что компьютер “не знает”, какие детали рисунка важны для нашего восприятия. Если при уменьшении исчезнут важные детали, результат будет ужасным. Если исчезнут второстепенные детали, качество восприятия ухудшится, но общее впечатление останется.

Чтобы проиллюстрировать возможность вставки в список графических маркеров, воспользуемся одним из примеров предыдущей главы — веб-страницей фирмы “Лентяй”. Если помните, там мы создали два списка: маркированный (список услуг) и нумерованный (порядок оформления заказа). Теперь, допустим, мы хотим заменить кружки в маркированном списке на красные треугольники.

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

<UL TYPE="disc">

Чтобы пойти дальше, чуть приподнимем завесу над материалом главы 4 и заменим атрибут TYPE= на атрибут STYLE= (как, кстати, и положено делать в соответствии со спецификацией HTML 4.0):

<UL STYLE="list-style-type: disc;">

Теперь, чтобы заменить кружок на графический маркер, заменим свойство list-style-type на свойство list-style-image и определим местоположение нашего файла-рисунка:

<UL STYLE="list-style-image: url('Images/markerl.gif);">

Вот и все! Можно наслаждаться списком с графическими маркерами. Обратите внимание на то, что при указании имени файла мы заключили его не в обычные двойные кавычки, а в одинарные. Это сделано потому, что все значение атрибута STYLE= заключено в двойные кавычки. Поэтому если бы мы ошибочно написали

<UL STYLE="list-style-image: uri("Images/marker1.gif");">

то кавычка перед словом Images была бы воспринята как закрывающая, то есть атрибуту STYLE= было бы присвоено значение "list-style-image: url(", a все, что следует за этим, стало бы еще одним, нераспознанным атрибутом тега <UL>.

Оформление кнопок

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

Чтобы создать кнопку, достаточно поместить некоторый текст между тегами <BUTTON> и </BUTTON> , например, вот так:

<BUTTON>ЭТO KHОПKА</BUTTON>

Правда, повторим, из этого совершенно не следует, что при нажатии на этой кнопке что-нибудь произойдет. Однако кнопка будет вполне полноценной и даже будет “вдавливаться” при нажатии.

Вообще говоря, такие кнопки можно было создать и в старых версиях языка HTML, хотя там не было тега

< BUTTON > . Интереснее тот факт, что между тегами <BUTTON>...</BUTTON> можно поместить не только текст, а все, что угодно. Если мы поместим туда тег <IMG> , то получим кнопку с графическим изображением. Можно поместить на кнопку и текст, и изображение (только не надо забывать о форматировании — например, надо вставлять теги <BR> для переноса строк и т. д.). Наконец, как показано в следующем примере, можно поместить на кнопку вообще любой блок

НТМL! В нашем примере мы поместили туда целую таблицу с разноцветными клетками.

Итак, проиллюстрируем сказанное таким файлом.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">

<HTML>

<HEAD>

<TITLE>KHOПKИ</TITLE>

<STYLE>

TD {color: white;} </STYLE>

</HEAD> <BODY> <BUTTON>ПРОСТО КНОПКА</BUTTON>

<BR><BR>

<button><img SRC="Images/email_b-l.gif" BORDER="0" WIDTH="26"

HEIGHT="23" ALT=""></BUTTON><BR><BR>

<BUTTON>Internet Explorer<BR>

<IMG SRC="Images/ie4.jpg" WIDTH="62" HEIGHT="61" BORDER="0"><>BR> 4.0 </BUTTON><BR><BR> <BUTTON><H1> Это большая кнопка</Н1>

<TABLE
ALIGN="center" BGCOLOR="#408080"
WIDTH="280" CELLSPACING="2"
CELLPADDING="2" BORDER="3">

<TR>

<TD ALIGN="center" BGCOLOR-"#400040">Oнa содержит</ТD>

<TD ALIGN="center">целую таблицу</ТR> </TR> <TR>

<TD ALIGN="center">c разноцветными</ТD>

<TD ALIGN="center" BGCOLOR="#400040">Клеточки</TD> </TR>

</TABLE>

<BR>И ГОРИЗОНТАЛЬНУЮ ЛИНИЮ <HR WIDTH="400" SIZE="10" COLOR="Navy"> </BUTTON> </BODY>

</HTML>

Кстати, вторую и третью кнопку можно использовать как шаблон для дальнейшей работы: кнопка с конвертом вполне подойдет для отсылки сообщения электронной почты, а следующая подходит для ссылки на новую версию Internet Explorer (возможно, вам потребуется такая ссылка, если ваш документ будет оптимизирован под этот броузер).

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

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


3.5

3.5. Подготовка рисунков в программе Xara Webstyle

Мелкие графические элементы оформления, которые мы рассматривали в разделе 3.3, удобно готовить в программе, которая называется Xara WebStyle. Эта программа узкоспециализирована — она предназначена только . для создания мелких графических элементов оформления, и ни для чего другого. Такая узкая специализация — одновременно и достоинство, и

недостаток. Достоинство — потому что даже неподготовленный пользователь может быстро сделать в ней все, что нужно. Недостаток — потому что, если у вас богатая фантазия, в скором времени вы исчерпаете ее возможности и вам станет “тесно” в ее рамках. Однако помните, что вы все равно сможете воспользоваться этой программой для получения промежуточного результата, который впоследствии можно “довести до ума” в полноценном графическом редакторе.

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

• обычные заголовки (Headings);

• трехмерные заголовки (3D Headings);

• фоновые рисунки (Backgrounds);

• кнопки (Buttons);

• графические маркеры (Bullets);

• горизонтальные полосы-разделители (Dividers).

Выбор шаблона

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

Настройка параметров рисунка

Выбрав шаблон, приступим собственно к созданию нашего элемента. Для этого можно воспользоваться кнопками, расположенными в левой части экрана: Text (Текст), Color (Цвет), Texture (Текстура), Shadow (Тень) и Size (Размер).

Чтобы ввести текст заголовка, нажмите кнопку Text. Далее можно набрать любое словосочетание, а также выбрать шрифт, которым оно будет начертано. Шрифт выбирается любой из числа установленных в операционной системе. Все происходящие изменения тотчас же отображаются в области просмотра. Удобно, что название каждого шрифта отображается самим этим шрифтом (кроме тех случаев, когда шрифт не алфавитный, например Maestro или Wingdings).

Нажатие на кнопку Color (Цвет) открывает возможность выбора цвета будущего заголовка. В зависимости от выбранного шаблона этих цветов может быть несколько. Например, шаблон заголовка Embossed (Тиснение) позволяет выбрать три цвета: цвет светлых краев, цвет темных краев и цвет тени. Кроме того, обычно есть еще возможность выбрать цвет фона (Background color), которая не влияет, собственно, на наш элемент, однако может помочь в его настройке, если заранее известно, на каком фоне он будет расположен.

Для выбора цвета предлагается интересная палитра, составленная из 216 (36х6) цветов и шести градаций серого цвета. Один из предлагаемых цветов выбирается щелчком мыши. Если же этих цветов недостаточно, можно нажать кнопку Advanced (Дополнительно) и перейти к выбору цвета из полной TrueColor-палитры или даже ввести код цвета в цифровом виде, указав насыщенность красной, зеленой и синей составляющей в процентах или абсолютных значениях (десятичных или шестнадцатеричных), а также ввести параметры цвета в режиме HSV.

Кнопка Texture позволяет выбрать текстурное покрытие для графического элемента. Возможность наложения текстур также зависит от шаблона. Как и в предыдущем случае, предоставляется возможность выбора фоновой текстуры для просмотра.

Следующая кнопка, Shadow, позволяет отрегулировать тени, отбрасываемые графическим элементом. Для начала предлагаются восемь вариантов отбрасываемой тени. Если они не устраивают, нажмите на кнопку Advanced (Дополнительно) — откроется окно, средствами которого тени можно настроить аккуратнее. В левой части этого окна задают тип тени (Wail — тень, падающая на стену, или Floor — тень, падающая вниз, “ на пол ”; есть еще вариант None — без тени). В следующем разделе (projection) можно задать угол отбрасывания тени и ее размер по вертикали (в процентах). И, наконец, в правой части окна задают насыщенность тени (darkness) и степень размытия ее краев (blur).

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

Выбор способа сохранения

Когда графический элемент создан, его нужно сохранить в оптимальном виде — чтобы качество было получше, а размер поменьше. Для этого в программе Xara WebStyle есть очень наглядная утилита. Если нажать на кнопку Save (Сохранить), открывается диалоговое окно, в котором можно выбрать тип файла — GIF или JPEG и размер файла (Fast Download — для быстрой загрузки, низкое качество; Medium Quality — среднее качество и средний размер, и High Quality — высокое качество, но и размер побольше). А если нажать на кнопку Advanced (Дополнительно), можно тонко настроить все параметры сохранения файла. Для формата JPEG это стандартная шкала качества (от 0 до 100), а для формата GIF можно выбрать количество цветов (16 или 256), палитру, режим передачи полутонов, режим чересстрочной развертки и режим прозрачного рисунка. В последнем случае с помощью движка Trim transparency можно выбрать количество цветов, которые будут преобразованы в цвет, назначенный прозрачным. Самое замечательное, что во время всех этих манипуляций их результат можно непосредственно наблюдать в области просмотра, и контролировать при этом размер получающегося файла (указывается в нижней части панели предварительного просмотра). Кроме того, можно нажать на кнопку Browser Preview (Просмотр в броузере) и просмотреть результат работы так, как он будет выглядеть в броузере. При этом выдаются также дополнительные сведения, например время загрузки данного файла при различной производительности модемного соединения с Интернетом.

Обратите внимание на то, что в левом нижнем углу рабочей области практически всегда расположена кнопка Revert (Возврат), позволяющая сделать несколько “откатов” назад, если совершена трудноисправимая ошибка. А в правом нижнем углу часто располагается кнопка Theme (Тема), при нажатии которой предлагаются несколько заранее подобранных вариантов цвета, шрифта и т. п.

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

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


3.6

3.6. Подготовка рисунков в программе Adobe Photoshop

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

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

Рис. 3.8. Основное окно программы Adobe Photoshop

Пример 1. Создание градиентного фона

Рис, 3.9. Инструменты, программы Adobe Photoshop

В программе Adobe Photoshop выберем из меню Файл (File) пункт Новый (New). Появится диалоговое окно создания нового файла (рис. 3.10). Внем нас больше всего интересует задание размера будущего изображения, его ширины и высоты. В раскрывающихся списках выберите единицы измерения — пикселы, так как нас интересует именно экранный размер изображения.

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

“Вся ширина экрана” — понятие растяжимое, однако редко кто смотрит веб-страницы в разрешении, большем, чем 1024х768, поэтому для большинства случаев размера 1024 точки по горизонтали будет достаточно.

Рис. 3.10. Создание нового изображения в программе Photoshop

Итак, определяем ширину рисунка: 1024 и высоту: 2 пиксела. Остальные параметры нам сейчас не важны. После щелчка на кнопке ОК откроется окно рисунка. Чтобы лучше видеть результаты своих действий, желательно увеличить масштаб изображения, нажав несколько раз комбинацию клавиш CTRL++.

Теперь надо выбрать цвета для создаваемого градиента, например, как в нашем примере: зеленый и светло-зеленый. Для выбора первого цвета дважды щелкните на значке Основной цвет (Foreground Color) — откроется окно выбора цвета (Color Picker), в котором можно визуально выбрать необходимый цвет. Для выбора второго (конечного) цвета градиента дважды щелкните на значке Цвет фона (Background Color).

Выбрав цвета, можно определить характер градиента. Для этого выберите инструмент Градиент (Linear Gradient Tool) на Панели инст- рументов. Далее, удерживая в нажатом положении клавишу SHIFT, проведите линию от левого края рисунка до приблизительно 200-й слева точки 1 . Когда кнопка мыши будет отпущена, вы увидите градиентную заливку. Осталось только сохранить рисунок.

Однако, выбрав пункт Сохранить (Save) из меню файл (File), вы, скорее всего, увидите, что среди предлагаемых форматов, в которых можно сохранить изображение, есть только формат PSD (собственный формат программы Adobe Photoshop). Это происходит потому, что наше изображение содержит более одного слоя. Выберите из меню Слой (Layer) команду Склеить все слои (Flatten Image), после чего вновь попытайтесь сохранить файл. Теперь в окне сохранения вам будет предложено множество форматов, из которых следует выбрать формат JPEG. Далее требуется выбрать качество сжатия по десятибалльной шкале. В данном случае для приемлемого результата достаточно выбрать значение 3 или 4.

И еще несколько замечаний по поводу первого примера. Во-первых, избран ный нами размер 1024 точки по горизонтали явно избыточен, ведь нари сованный нами градиентный перелив заканчивается уже на 200-й точке. Если вы используете каскадные таблицы стилей (CSS) на веб-странице, у вас будет возможность НЕ повторять фоновый рисунок по горизонтали. Тогда можно спокойно создать рисунок шириной 200 точек и запомнить конечный цвет градиента (разумеется, не на глаз, а в цифровом выра жении — в окне выбора цвета отображаются значения R, G, В, то есть крас ной, зеленой и синей составляющих). А затем помимо фонового рисунка определить на веб-странице цвет фона, совпадающий с конечным цветом градиента. Далее можно таким же способом назначить вертикальный градиент, однако делать это следует только если используются каскадные таблицы стилей CSS, поскольку лишь в этом случае можно не повторять фоновый рисунок по вертикали.

И, наконец, можно создать многократный градиентный перелив. Для этого, выбрав инструмент Градиент (Linear Gradient Tool), выберите в служебной палитре Навигатор/Инфо/Опции (Navigator/Info/ Options) вкладку Опции линейного градиента (Linear Gradient Options) и нажмите кнопку Правка (Edit)— откроется диалоговое окно Редактор градиента I (Gradient Editor), представленное на рис. 3.11. Здесь можно по желанию добавить в любое место градиента любой цвет, а также цвет пере- днего плана и цвет фона, пользуясь, соответственно, одним из трех значков настройки параметров градиента. Все изменения немедленно отображаются на экране. Таким образом, наш градиент может переливаться не двумя, а тремя, четырьмя и более цветами. Когда найдете нужное сочетание цветов, нажмите кнопку ОК и затем, как и ранее, проведите линию инструментом Градиент (Linear Gradient Tool).

Пример 2. Подготовка круглой фотографии

Как вы помните, на рис. 3.6 была изображена веб-страница с круглой фото графией. Посмотрим, как же такую фотографию подготовить, если у нас есть обычная фотография.

На панели инструментов выберите инструмент простого выделения (Rectangular Marquee Tool). Нажмите и удерживайте на его значке левую кнопку мыши, пока не появится небольшое меню из не- скольких подобных значков. Эти инструменты называются альтернативными. Выберите из набора альтернативных инструментов инструмент круглого или овального выделения (Elliptical Marquee Tool). лите на рисунке нужную часть, а затем нажмите комбинацию клавиш SHIFT+CTRL+1 или выберите в меню Выделить (Select) пункт

Рис. 3.11. Исходная

Рис. 3.12. Очистка

Рис. 3.13. фотография ненужных областей.

Кадрированньй снимок

Обратно (Inverse). При этом на рисунке будет выделено все, кроме обведен ной области. Затем в меню Правка (Edit) выберите пункт Очистить (Clear). Результат показан на рис. 3.12.

Чтобы удалить ненужные пустые области изображения, снова откройте набор альтернативных инструментов выделения и выберите инструмент простого прямоугольного выделения (Rectangular Marquee Tool). Обведите круглую или овальную фотографию и дайте команду Изображение > Обрезание (Image > Crop). Результат показан на рис. 3.13.

Теперь осталось сохранить эту фотографию так, чтобы цвет фона вокруг нее превратился в прозрачный. Удобнее и нагляднее всего это сделать следующим образом. Дайте команду Изображение > Режим > Индекс цвета (Images Mode > Indexed Color) В открывшемся диалоговом окне установите необходимое количество цветов. В случае фотографии обычно желательно установить адаптированную (Adaptive) палитру из 256 цветов. Если помните, это максимальное количество цветов для формата GIF. Нажмите кнопку ОК для преобразования цветового режима и затем дайте команду Файл > Экспорт > GIF89a (File > Export > GIF89a Export). Появится диалоговое окно Экспорт опции (GIF 89a Export Options), представленное на рис. 3.14. Возьмите в нем инструмент Пипетка (Eyedropper Tool) и щелкните им на фоне изображения. Оно окрасится в серый цвет, который условно принят для воспроизведения прозрачного цвета. При необходимости можно с помощью пипетки еще некоторые цвета преобразовать в цвет, назначенный прозрачным. Затем нажмите на кнопку ОК и все. Остается только ввести имя файла.

Рис. 3.14. Выбор цвета, который будет отображаться как прозрачный

Пример 3. Подготовка рисунков произвольной формы

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

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

Рис. 3.15. Подготовка изображения произвольной формы

Для выделения объектов произвольной формы в программе Adobe Photoshop имеются такие инструменты, как Лассо (Lasso Tool) и Волшебная палочка (Magic Wand Tool). С помощью инструмента Лассо (Lasso Tool) можно вручную провести контур выделения произвольной формы, что в нашем случае возможно, хотя и трудоемко. С помо- щью Волшебной палочки (Magic Wand Tool) можно мгновенно выделить объект по контуру, но только при условии, что контур заполнен одним цветом или близкими цветами. Если же контур размыт (как бывает на большинстве реальных фотографий), то иногда программа определяет его не так, как человеческий глаз. В любом случае можно добавить к выделенной области еще кусочек, если щелкнуть волшебной палочкой, удерживая клавишу SHIFT.

В нашем примере можно, несколько раз щелкнув волшебной палочкой в левой верхней части фотографии, выбрать все, что находится слева и сверху от лица, и затем дать команду Правка > Очистить (Edit > Clear). На рис. 3.29 можно заметить, что все-таки в очищенной области остался неко торый “мусор”. Его легко почистить, используя инструмент Ластик (Eraser). Увеличьте масштаб изображения, нажав несколько раз комбина цию клавиш CTRL++. Чтобы “стереть” ненужные детали, доста точно поводить по ним инструментом при нажатой кнопке мыши, только не забудьте выбрать подходящий размер ластика. Для этого в служебной палитре Цвета/Каталог/Кисти (Colors/Swatches/Brushes) выберите вкладку Кисти (Brushes) и в ней подберите подходящий размер инструмента. Обычно для стирания мелкого мусора лучше всего подходит жесткий инструмент диаметром пять пикселов (по умолчанию третий слева в верхнем ряду).

Главное при удалении мусора — не задевать контур изображения. Для верности можно предварительно выделить всю область с мусором любым из инструментов выделения. Если на рисунке присутствует выделенная область, то все действия, в том числе и стирание, производятся только внутри нее. Итак, после стирания у нас должно получиться изображение, подобное представленному на рис. 3.15. После этого остается только сохранить наш файл, назначив цвету фона свойство прозрачности, как в предыдущем примере. Однако, пользуясь случаем, рассмотрим еще один момент. Перед сохранением изображения неплохо бы проверить его размер в пикселах. Для этого дайте команду Изображение > Размер изображения (Image > Image Size). Она откроет диалоговое окно Размер изображения (Image Size), представлен ное на рис. 3.16. В нашем примере исходный размер изображения был равен 1437х958 пикселов, что явно превосходит возможности большин ства экранов. На веб-странице такая большая фотография будет смотреться плохо. Поэтому перед сохранением неплохо бы уменьшить ее размер. Это можно сделать в том же диалоговом окне, поменяв значения ширины и/или высоты. Предварительно надо установить флажок Ресэмплировать Изображение (Resample Image) и желательно проследить, чтобы при этом был установлен флажок Соблюдать пропорции (Constrain Proportions). Пер вый флажок необходим, чтобы изображение перемасштабировалось не визуально, а физически — с удалением (при уменьшении) или вставкой (при увеличении) промежуточных точек, а второй — чтобы размеры сто рон изменялись пропорционально. При физическом изменении размеров рисунка следует выбрать тип интерполяции — от него зависит алгоритм выбора параметров промежуточных точек. Если изображение фотографи ческое, как в нашем случае, используют Бикубическую (Bicubic) интерполя цию . Если изображение штриховое или растровое (чертеж, снимок экранного окна и т. п.), целесообразно использовать интерполяцию По ближайшему соседнему (Nearest Neighbor).

Рис. 3.16. Изменение размера изображения в программе Photoshop

Пример 4. Совмещение изображений

С помощью программы Adobe Photoshop можно делать и более интересные манипуляции. Рассмотрим такой пример. Допустим, у нас имеется фотография, изображенная на рис. 3.17. В то же помещение мы желаем поместить яблоко с фотографии на рис. 3.17, то есть сделать простейший монтаж.

Рис. 3.17. Первая исходная фотография для монтажа

Рис. 3.18. Вторая исходная фотография для монтажа

Сначала с помощью инструмента Волшебная палочка

Рис. 3.18. Обтравка изображения по контуру

Итак, выберем из меню Правка (Edit) пункт Трансформ (Transform) и далее дадим команду Перевернуть по горизонтали (Flip Horizontal). В результате получится то, что изображено на рис (ниже). Конечно, делать зеркальные изображения людей, строго говоря, не совсем корректно, поскольку доказано, что зеркальное изображение воспринимается совсем не так, как обычное. Однако для данного случая его можно считать приемлемым. Плохое освещение скрадывает отличия зеркального образа, но для композиции он хорошо подходит из-за наклона вправо.

Рис. 3.19. Двухслойное изображение в программе Photoshop

— А дело в том, что здесь мы подошли к одному из самых замечательных свойств программы Adobe Photoshop — умению работать со слоями. Любое изображение может состоять из нескольких слоев, которые можно произвольно располагать один над другим. Если в изображении присутствуют несколько слоев, то все манипуляции происходят только с тем слоем, который выделен на служебной палитре Слои (Layers). В нашем случае в момент вставки изображения из буфера обмена для него автоматически был создан новый слой. Таким образом, сейчас в нашем рисунке два слоя (рис. 3.21). Тот слой, который выделен, считается текущим. Поэтому все, что мы делаем, сейчас относится только к нему. Кстати, обратите внимание на то, что один из слоев на рис. 3.21 называется Фон (Background). Такой слой обязательно присутствует в каждом многослойном рисунке, и при этом он является самым нижним.

Рис. 3.20. Эффект зеркального отражения одного из слоев

Рис. 3.21. Список слоев в программе Photoshop

Рис. 3.22. Числовые преобразования в программе Photoshop

Итак, попробуем разместить наше вставленное изображение. Для того чтобы его уменьшить, дайте команду Правка > Трансформ > Число (Edit > Transform > Numeric). Она открывает диалоговое окно (рис. 3.22), в котором можно задать параметры преобразования текущего слоя. В нашем случае следует оставить включенным только флажок Масштаб (Scale). Установите также флажок Соблюдать пропорции (Constrain Proportions) и задайте ширину объекта 70% (при этом высота также автоматически изменится). Затем возьмите инструмент Двигатель (Move Tool) и с его помощью передвиньте изображение девушки, как показано на рис. 3.23.

Получается не совсем то, что надо. Яблоко находится как бы дальше от нас, чем остальное, однако ее изображение перекрывает их! Что делать? Можно, конечно, выделить из фона изображение, скопировать его на новый слой и поместить этот слой впереди всех остальных. Кстати, для упражнения можете проделать такую работу. Но мы для простоты просто поместим изображение девушки чуть левее, чтобы оно не перекрывало другие близкие к наблюдателю объекты.

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

Рис. 3.23. Перемещение слоя

Рис. 3.24. Изменение масштаба

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

Вернувшись к моменту уменьшения изображения, снова дадим команду Правка > Трансформ > Число (Edit > Transform > Numeric) и зададим масштаб изображения, равным 85% (рис. 3.24). Теперь передвинем изображение яблока (рис. 3.25). Что ж, теперь общая картина стала гораздо естественнее. Но все же той тени, которую мы “взяли с собой”.

Чтобы было легче выделить “старую” тень, щелкните на значке глаза слева от слоя Фон. При этом фон исчезнет с экрана. Увеличьте изображение девушки с помощью комбинации CTRL++. Теперь нужно выбрать подходящий инструмент для выделения. Если вы хорошо и гибко умеете водить мышью, можете выбрать инструмент Лассо (Lasso), но, на наш взгляд, здесь удобнее воспользоваться инструментом многоугольного выделения (Poligonal Lasso Tool). Этот инструмент альтернативен инструменту Лассо (Lasso). Его выбирают, как и все альтернативные инструменты, наведя указатель мыши на текущий инструмент, нажав кнопку и дождавшись открытия меню альтернативных инструментов.

Щелкая по вершинам многоугольника, выделите “старую” тень и удалите ее командой Правка > Очистить (Edit > Clear). Теперь опять щелкните слева от слоя Фон в служебной палитре Слои (Layers), чтобы вернуть на экран фоновое изображение (рис. 3.25).

Рис. 3.25. Перемещение слоя за рамки кадра

Рис. 3.26. Удаление “лишней” тени из слоя

Теперь осталось собственно наложить тень. Из меню Слой (Layer) выберите пункт Эффекты (Effects) и далее команду Наложить тень (Drop Shadow). Откроется диалоговое окно настройки эффектов (рис. 3.27). Обратите внимание на то, что если отмечен флажком пункт Применить (Apply), то, настраивая эффект, можно непосредственно наблюдать результат его действия на изображение.

Градиентная заливка

Рис. 3.27. Окно настройки эффектов применительно к слою изображения

В соответствии с освещенностью на фоновой фотографии выберите режим Мягкий свет (Soft Light). При этом следует немного уменьшить заданную прозрачность, например до 67%. Опытным путем подберите угол отбра сывания тени (Angle) — в нашем случае — 146%, а также “дистанцию” (Distance) (удаленность от основного изображения, в нашем случае — 13 пикселов) и глубину размытия (здесь — 11 пикселов). На рис. 3.28 пока зано, что должно получиться в результате.

Наконец, обрежем правый и нижний края изображения, чтобы создать подобие художественной композиции. Эта операция называется кадриро ванием. Взяв инструмент для прямоугольного выделения, выделим нуж ную часть изображения и дадим команду Изображение > Обрезание (Image > Crop). Окончательный результат показан на рис. 3.29). Теперь оста лось только сохранить свою работу. Чтобы сохранить расположение слоев и их эффекты, необходимо использовать формат PSD. Но для представления в Интернете он не подходит, поэтому рекомендуется сохранить свою работу дважды. Первый раз она сохраняется в формате PSD — этот файл можно использовать впоследствии для внесения в него новых изменений. Рис. 3.28. Наложение тени на слой если потребуется. Перед вторым изображения

Рис. 3.28. Законченная композиция после кадрирования

сохранением (в формате JPEG) необходимо “спрессовать” все слои в один, так как раздельно хранить информацию о слоях можно только в формате PSD. “Сплющивание” изображения выполняют командой Слой > Склеить все слои (Layer > Flatten Image). После этого его можно сохранить в любом формате, в том числе и в формате JPEG.


Пример 5.

Пример 5. Украшение изображения мелкими деталями

Иногда возникает потребность немного приукрасить имеющееся изображение, чтобы придать ему своеобразный колорит. Рассмотрим такой пример. Взгляните на фотографию. Чтобы придать этому изображению некий “морозный” колорит, неплохо украсить ее передний план узором в виде снежинок. Для этого попытаемся нарисовать снежинку и разбросать ее изображение по фотографии, чтобы получился как бы вид сквозь узорное стекло.

Чтобы нарисовать снежинку, создайте новый файл изображения небольшого размера, например 50х50 пикселов. Теперь возьмите инструмент Линия (Line Tool). Если его нет на панели инструментов, то знайте, что он альтернативен инструменту Карандаш (Pencil Tool) — там его и ищите. Когда инструмент выбран, откройте служебную палитру Опции линии (Line Options) и задайте в поле Вес (Weight) значение 2 (пик села) — это будет ширина наших линий. Установите флажок Сглаживание (Anti-alised) и сбросьте флажки Старт (Start) и Конец (End) в разделе Стрелки как было сделано в предыдущем примере, дав команду Правка > Трансформ > Число (Edit > Transform > Numeric), а затем установив масштаб, например, 85%. Теперь еще раз выделим сне жинку и снова выберем в контекстном меню палитры кистей пункт Заданная кисть (Define Brush) — получим вторую кисть. Повторим все это еще раз, и получим третью кисть. Теперь у нас в палитре кистей имеются три кисти в виде снежинок разных размеров.

Установим белый цвет в качестве основного и попробуем рисовать новыми кистями. Для нашего случая лучше всего подойдет инструмент Аэрограф (Airbrush Tool). Дело в том, что при рисовании этим инструментом цвет будет тем интенсивнее, чем дольше держится нажатой кнопка мыши. Если выбрать из палитры кистей одну из снежинок и щелкнуть мышью в любом месте на фотографии, то на месте щелчка появится снежинка. А если отпустить кнопку мыши не сразу, снежинка получится более белой. Так можно, щелкая по разным местам фотографии, быстро “размножить” на ней снежинку.

Кстати, в качестве упражнения можно проделать следующее. Дважды щелкните в палитре кистей на изображении снежинки и установите параметр Spacing большим, чем 100% (например, 125%). Теперь возьмите инструмент Кисть (Brush Tool) и попробуйте просто вести ею по рисунку. За кистью будет оставаться след в виде шлейфа снежинок. Таким образом, созданные кисти можно в полной мере использовать для рисования. А параметр Spacing задает расстояние между объектами при “рисовании непрерывной линии”.

Пример 6. Заливка и заполнение объектов текстурами

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

Допустим, у нас есть вид, изображенный на рис. 3.29. Если потребуется, к примеру, сделать основу на фотографии белоснежное покрытие, достаточно выбрать белый цвет в качестве основного, а затем в выбрать инструмент Заливка (Paint Bucket Tool). Щелкнув несколько раз в разных местах дороги, изображенной на фотографии, можно получить следующий результат (рис. 3.30). Как видите, здесь даже не требуется беспокоиться о предварительном выделении нужной области, так как заливка осуществляется по контуру. Правда, если присмотреться, то все равно неизбежно придется удалять “мусор” (здесь это удобно сделать с помощью инструмента Карандаш (Pencil Tool).

Выбрав инструмент для прямоугольного выделения, выделите область на газоне так, чтобы в нее попала только трава. Затем дайте команду Прав ка > Определить образец (Edit > Define Pattern). При этом, как будто, ничего не произой-

Рис. 3.29. Исходный снимок

Рис. 3.30. Результат заливки

Инструмент Карандаш (Pencil Tool) альтернативен инструменту Линия (Line Tool). О том, как выбирают альтернативные инструменты (если их нет на панели инструментов), вы уже знаете.

Теперь нажмите комбинацию клавиш CTRL+D, чтобы снять выделение.

Выберите инструмент Узорный Штамп (Pattern Stamp Tool). На палитре кистей выберите круглую кисть подходящей величины (например, шестую во втором ряду — мягкую кисть диаметром 27 пикселов). Теперь можно, нажав кнопку мыши, перемещать указатель по рисунку дороги — при этом дорога будет “зарастать” травой. В результате получится изображение, похожее на представленное на рис. 3.31.

Кстати говоря, можно взять образец текстуры и из любого другого изображения. Например, если бы потребовалось дорогу на рис. 3.29 залить водой, которой на этой фотографии нет, то достаточно было бы найти другой пейзаж с водным пространством (рис. 3.32), выделить прямоугольную область, содержащую только воду, и сделать ее образцом текстуры командой Правка >Определить образец (Edit > Define Pattern). Затем можно открыть файл нашего пейзажа, выделить дорогу с помощью Волшебной палочки (возможно, придется щелкнуть несколько раз, удерживая клавишу SHIFT), чтобы ненароком не налить воды, куда не нужно, и, выбрав инструмент Узорный штамп (Pattern Stamp Tool).

Пример 7. Наложение текста

Иногда хочется встроить в изображение текстовый материал. Допустим, вы задумали сделать открытку для дня рожденья . Логично разместить на ней надпись “Happy Birfday”. Хорошо бы ее разместить не как попало, а вдоль линии бортика моста, чтобы не разрушать композицию.

Рис. 3.31.

Рис. 3.32.

Итак, приступим. Из палитры инструментов выберите инструмент Текст (Type Tool) и щелкните мышью там, где предполагается начать -текстовое сообщение. Появится окно ввода текста (рис. 3.33).

Рис. 3.33. Ввод текста в программе Adobe Photoshop

В нем определим цвет будущего текста Happy Birthday, его размер (в данном случае 40 пункта) и шрифт (мы выбрали Regular). Теперь можно в нижнюю часть окна вводить сам текст. Во время ввода можно наблюдать появление текста прямо на рисунке. Закончив ввод, нажмите ОК. То, что получилось, представлено на рис. 3.34.

Как видите, текст не поместился на рисунке. Поэтому возьмем инструмент Двигатель (Move Tool) и подвинем текст влево так, чтобы он занял всю ширину рисунка. Теперь давайте придадим нашему тексту объемность. Выберите из меню Слой (Layer) пункт Эффекты (Effects) и дайте команду Рельефность (Bevel and Emboss). Немного настроив эффект “на глаз”, нажмите ОК. Получится приблизительно то, что изображено на рис (далее)

Рис. 3.34. Наложение текста на фотографию

Для переворота текста служит команда Правка >Трансформ > Вращать (Edit >Transform > Rotate). Вокруг нашего текста появятся маркеры, за которые его легко повернуть, нажав кнопку мыши и перемещая ее указатель. Повернув текст на нужный угол, нажмите клавишу ENTER. Появится диалоговое окно с запросом, надо ли преобразовать изображение. Ответьте на него утвердительно.

Для большей естественности нужно нашему тексту добавить перспективу. Однако функция Трансформ > Перспектива (Transform > Perspective) недоступна для текстовых слоев. Поэтому придется сначала создать новый слой командой Слой > Новый > Слой (Layer > New > Layer), затем сбросить флажок видимости фонового слоя (тот, что в виде глаза на служебной палитре слоев) и выбрать в меню Слой (Layer) команду Склеить с видимым (Merge Visible). При этом наш текстовый слой склеится с новым слоем, а фон останется в отдельном слое. После этого восстановите отображение фона.

Убедившись, что выделен наш новый слой, а не фон, можете дать команду Правка > Трансформ > Перспектива (Edit > Transform > Perspective). Перспективиза-ция, как и вращение, тоже выполняется низуально с помощью маркеров, которые появляются вокруг изображения. После трансформации нам останется еще немного подкорректировать наклон текста командой Правка > Трансформ > Наклон (Edit> Transform > Skew). В результате получится изображение, подобное представленному на рис. 3.35.

Здесь все было бы хорошо, но слово “Welcome” вылезает куда-то в небо и портит картину. Его необходимо подви-

Рис. 3.35. Придание тексту рельефности

Рис. 3.36. Надпись с наклоном

нуть вниз. Для того чтобы это сделать, сбросьте флажок видимости у слоя Фон (Background) и выберите инструмент многоугольного выделения — только с его помощью (или с помощью инструмента Лассо) удастся выделить слово “Welcome”. Выделив его, верните флажок видимости фоновому слою и с помощью инструмента Двигатель (Move Tool) подвиньте выделенное слово вниз, (рис. 3.37). Теперь наше изображение выглядит вполне пристойно.

Заключение

Завершая этот краткий обзор приемов работы с программой Adobe Photoshop, хочется заметить, что за его рамками, разумеется, остались многие возможности программы, например такие, как фильтры, позволяющие размыть изображение, сделать его похожим на барельеф или акварель, добавить шум и т. п. Однако полное описание возможностей этой программы выходит за рамки данной книги. Тем, кто заинтересовался работой в Adobe Photoshop, можно посоветовать обратиться к специальной литературе (см., например, М. Стразницкас. Photoshop 5.5 для подготовки Web-графики. Учебный курс. “Питер”, 2000).

Рис. 3.37 Перемещение выделенной области в одном слое


Изображение-

Изображение-карта

Теперь давайте рассмотрим более сложный пример. Представим себе, что надо сделать сайт, посвященный описанию старинного компьютера ATARI-800. Уже подготовлены файлы с описанием его монитора, самого компьютера и дисковода: monitor.html, computer.html и diskovod.html (мы для проверки работоспособности примера тоже создали такие файлы, но в них ничего нет, кроме заголовка). Наша задача: создать титульную страницу сайта и поместить на нее изображение компьютера (рис. 3.4).

При этом логично было бы сделать так, чтобы щелчок на изображении монитора переводил читателя на страничку с описанием монитора, щел чок на изображении дисковода — на страничку с описанием дисковода и щелчок на изображении самого компьютера — на страничку с его описанием. Можно, конечно, “разрезать” изображение на три и с каждого дать гиперссылку на соответствующий файл. Но при этом разрушится целостность композиции на фотографии компьютера. Что же делать?

Оказывается, есть возможность установить несколько гиперссылок с одного рисунка, не “разрезая” его! Такое изображение называется кар той графических ссылок (imagemap}. Создание карты графических ссылок — операция довольно кропотливая, но результат обычно довольно эффектен. Делается это так.

Вот, например, наш файл diskovod.html:

<HTML>

<НЕАD>

<ТIТLЕ>ДИСКОВОД</ТIТLЕ>

</НЕАD>

<ВODY>ОПИСАНИЕ ДИСКОВОДА</BODY>

</HTML>

Рис. 3.4. Изображение компьютера, из которого мы будем делать

графическую карту ссылок

1. Сначала рисунок внедряется на веб-страницу обычным образом, с помощью тега <IMG>:

<IMG
SRC="Images/computer.gif" WIDTH="451"
HEIGHT="310" BORDER="0"
ALT="ATARI-800">

2. Затем необходимо установить в этом теге атрибут USEMAP=. Его значение должно содержать имя карты графических ссылок, с предвари тельным знаком #, Если карта еще не создана, как в нашем случае, то ей можно дать любое имя:

<IMG
SRC="Images/computer.gif" WIDTH="451"
HEIGHT="310" BORDER="0"
ALT="ATARI-800" USEMAP="#compmap">

3. Теперь нужно создать собственно карту ссылок. Вообще говоря, эта карта может располагаться где угодно, хоть в другом файле — тогда в атрибуте USEMAP= нужно будет указать, кроме имени карты, имя этого файла, например: “mapfile.html#mymap”). В нашем случае давайте рас положим ее в конце того же файла.

4. Карта графических ссылок начинается с тега < МАР> и завершается зак рывающим тегом </МАР> . В теге <МАР> следует установить (обязательно!) единственный возможный атрибут NAME=. Его значением должно быть имя карты, на которое мы ссылались в теге <МАР> (с помощью атрибута USEMAP=). В данном случае это должно быть имя "compmap":

<МАР NAME="compmap">

5. Между тегами <МАР> и </МАР> должна находиться основная часть карты. Она состоит из нескольких тегов <AREA> , каждый из которых определяет активную область рисунка. (При щелчке мыши на “актив ных областях” может происходить перемещение по гиперссылке, а остальная часть изображения ничем не отличается от обычного рисунка.) В данном случае нам нужно определить три такие “активные области”: изображение монитора, компьютера и дисковода.

6. “Активные области” могут быть либо прямоугольной формы, либо круглой, либо многоугольной. Это определяется установкой значения атрибута SHAPE= в теге <AREA> (он употребляется без закрывающего тега). Если значение этого атрибута — "rect", область будет прямоугольной, если "circle" — круглой, а если "poly" — многоугольной.

7. Дальше начинается самое неприятное в составлении карты графических ссылок: нужно определить координаты каждой из активных областей и записать их как значения атрибута COORDS=.

Если “активная область” прямоугольная, то следует указать координаты левого верхнего ее угла и правого нижнего. Местоположение любой точки на рисунке может быть определено с помощью двух чисел — ее горизонтальной и вертикальной координат. Самая левая верхняя точка на рисунке имеет координаты “0,0”. Чем больше горизонтальная координата, тем правее расположена точка, и, соответственно, чем больше вертикальная координата, тем точка ниже. Например, если рисунок имеет размер 400х300 точек и нам нужно определить прямо угольнуюактивную область, занимающую его левый верхний угол и имеющую половину ширины и высоты рисунка, мы должны будем написать следующее:

<AREA SHAPE="rect" COORDS="0,0,200,150">

В этой записи атрибут COORDS= определяет прямоугольник с помощью двух точек: одна из них имеет координаты “0,0”, то есть левый верх ний угол, а другая — “ 200,150”, то есть это центральная точка рисунка размером 400х300.

Если “активная область” круглая, то задача немного упрощается: нужно определить координаты только одной точки — центра окружности, а также указать ее радиус, например:

<AREA SHAPE="circle" COORDS="200,150, 40">

Такая запись определяет круглую “активную область”, расположенную в центре нашего гипотетического рисунка размером 400х300 (координаты центральной точки— “200,150”). Окружность имеет радиус 40 точек.

И, наконец, самый сложный и наиболее часто встречающийся случай — многоугольная “активная область”. Здесь нужно последовательно

указать координаты всех углов многоугольника. Поскольку таких углов может быть очень много, то и значение атрибута COORDS= при обретает угрожающие размеры... Рассмотрим простой пример. Если на нашем рисунке размером 400х300 мы хотим определить область в форме равнобедренного треугольника, основание которого проходит ровно посередине рисунка, занимая всю его ширину, а вершина нахо дится посередине верхней границы рисунка, то это можно сделать так:

<AREA SHAPE="poly" COORDS="0,150,400,150,200,0">

Как видите, шесть координат определяют три точки — три угла нашего треугольника. В данном случае их последовательность не очень важна (можно было написать, например, "400,150,0,150,200,0"), но когда коли чество углов больше, становится важным порядок соединения точек. Например, записи

<AREA SHAPE="poly" COORDS="0,0,200,0,200,150,100,75,0,150">

И

<AREA SHAPE="poly" COORDS="0,0,200,0,100,75,200,150,0,150">

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

Отпугивающим моментом в этой технологии является то, что приходится каким-то образом выяснять координаты каждой нужной точки. На реальном рисунке это невозможно сделать “на глаз”, и приходится, к примеру, выяснять все координаты в каком-либо графическом редакторе, а уже потом переносить их в HTML-документ. К счастью, в послед них версиях некоторых HTML-редакторов (например, Allaire Homesite) имеются встроенные средства для установки координат на картах графических ссылок.

8. Однако атрибуты SHAPE= и COORDS= — это еще не все. В теге <AREA> необходимо установить еще самое главное — атрибут HREF=, определяющий гиперссылку, то есть куда же должен попасть пользователь при щелчке мышью на этой “активной области”. Здесь никаких сложностей нет — атрибут HREF= тега <AREA> ведет себя так же, как если бы он был в обычном теге <А> .

9. Кроме того, бывает полезно определить также атрибут ALT=. Его значе ние может содержать поясняющий текст, который будет “всплывать” при наведении мыши на “активную область”.

Итак, теперь мы можем попытаться обвести “активные области” нашего изображения компьютера (см. рис. 3.4). Естественно, что все они должны быть многоугольными, так как ни один из трех объектов не “укладывается” в прямоугольник или круг. Посмотрим, что получится в результате.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">

<HTML>

<HEAD>

<TITLE>Описание компьютера</TITLE>

</HEAD>

<BODY
BGCOLOR="#FFA940" TEXT="#1A1A1A"
LINK="#OOOOAO" VLINK="#OOOOAO"
ALINK="#OOOOAO">

<DIV ALIGN-"center"><H1>ATARI-800</Hl></DIV>

<DIV ALIGN="center"><BIG>3necь представлено описание старинного компьютера ATARI-800. Вот как он выглядел :</BIGX/DIV>

<DIV
ALIGN="center"><IMG
SRC="Images/computer.gif" WIDTH="451"
HEIGHT="310" BORDER="0"
ALT="ATARI-800"
USEMAP="#compmap"></DIV>

<DIV ALIGN="center">Для получения подробной информации о каждом узле щелкните на его изображении.</DIV>

</BODY> <МАР NAME="compmap">

<AREA ALT="МОHИTOР" SHAPE="poly"

COORDS="95,41,289,40,289,180,212,180,211,167,86,168,86,54" HREF="monitor.html">

<AREA
ALT="Koмпьютep ATARI-800" SHAPE="poly"
COORDS="7,253,57,255,62,265,156,265,158,259,205,259,213,247,210,178,
208,169,30,168,6,245" HREF="computer.html">

<AREA
ALT="Диcкoвoд" SHAPE="poly"
COORDS="293,197,345,154,438,168,441,196,437,224,400,265,294,
252,292,226" HREF="diskovod.html">

</МАР>

Результат этих трудов представлен на рис. 3.5. Как видите, на первый взгляд рисунок на страничке вполне обычный — наличие “активных областей” ничем не выдается. Поэтому необходима поясняющая подпись под рисунком.

Если поводить мышью над рисунком, то можно заметить, что над “актив ными областями” указатель мыши меняет свой вид, а если приостановить мышь над “активной областью” — появится соответствующая всплыва ющая надпись. И еще интересный момент: в большинстве броузеров можно воочию увидеть границы активных областей. Для этого надо нажать кнопку мыши на “активной области”, и, не отпуская ее, увести мышь за пределы области, и там отпустить кнопку. Тогда граница соответствующей “ актив ной области” останется выделенной.

Рис. 3.5. Страничка с графической картой ссылок


4

4. Оформление веб-страницы с использованием стилей

4.1. Оформление с помощью атрибута STYLE

В предыдущих главах мы рассмотрели некоторые способы создания веб- страниц, однако до сих пор почти ничего не говорили о том, как оформляют текст. И это не случайно. Дело в том, что в спецификации HTML 4.0 было рекомендовано использовать для оформления страниц новое мощное сред ство — каскадные таблицы стилей (CSS), которые мы сейчас и рассмот рим. При этом многие теги и атрибуты (собственно говоря, почти все, относящиеся к оформлению) были отменены, в том числе и некого рые из тех, что были рассмотрены нами ранее.

— Стоп! — скажете вы. — А для чего же мы их тогда рассматривали?

Не волнуйтесь, во-первых, мы почти не рассматривали отмененные теги, за исключением наиболее часто встречающихся, а во-вторых, отмена тегов в HTML 4.0 вовсе не означает, что всем нужно немедленно прекратить их использование. В некоторых случаях все равно бывает удобнее восполь зоваться одним из этих тегов, и этого не нужно бояться. Отмененные теги все еще поддерживаются текущими версиями броузеров, по крайней мере для совместимости со старыми веб-страницами. Скорее всего, они будут поддерживаться еще очень долго (как, например, до сих пор поддержива ются теги <ХМР> и <BL>, хотя первый из них не используется со времен HTML+, а второй вовсе никогда не входил в его спецификацию). Да и вообще, было бы странно, если бы новая версия какого-либо броузера вдруг “отказалась” от некоторых тегов — это явно не прибавило бы ей популяр ности. Так вот, отмена тегов означает, что WWW-консорциум не реко мендует более ими пользоваться, поскольку CSS действительно намного удобнее, и возможности автора при этом гораздо шире.

Атрибут STYLE

Итак, давайте начнем изучение оформления веб-страниц с использованием каскадных таблиц стилей CSS. И для начала рассмотрим такое понятие, как атрибут STYLE=.

Самый примитивный способ использования CSS — это ввести в код HTML атрибут STYLE= с соответствующим значением. Его можно добавить практически ко всем тегам (кроме таких, как, например, <HEAD> и <HTML> ). Таким образом, вместо отмененных атрибутов в HTML 4.0 всегда следует применять атрибут STYLE=.

Давайте рассмотрим пример. Возьмем для начала веб-страничку из вто рой главы (“Домашняя страница Сергея Сергеева”, см. рис.2.8), в кото рой немного использовались отмененные теги и атрибуты, и попробуем “переписать” ее по всем правилам HTML 4.0, сохранив пока что старое оформление.

Во-первых, вместо

<BODY
BGCOLOR="#BABAAO" TEXT="#1D1D18"
LINK="#634438" VLINK="#634438"
ALINK="Black">

рдует написать так:

Кстати, возможен и более простой вариант:

<Н1 ALIGN="centerг">Домашняя страница Сергея Сергеева</Н1>

Вместо этого применим атрибут STYLE= взамен отмененного атрибута ALIGN= и напишем:

<Н1 STYLE="text-align: center;">Домашняя страница Сергея Сергеева</Н1>

Этому атрибуту соответствует свойство text-align, принимающее те же зна чения, что и атрибут ALIGN=. Точно так же выровняем следующий тег <DIV>.

Замена тегов на стилевое описание

В следующем блоке использован отмененный тег <FONT>:

<FONT SIZE="+1"><В>Сергей Сергеев</В> - писатель-авангардист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.<BR><BR>

Некоторые его рассказы вы можете прочитать прямо здесь.<BR>&nbsp;</FONT>

Вы можете спросить, что если атрибут STYLE= легко заменил отмененные атрибуты, то что делать с отмененными тегами? К чему “прикрепить” атри бут STYLE=? В большинстве случаев его можно “прикрепить” к тегу <DIV>. В данном случае мы так и поступим:

<DIV STYLE="font-size: larger;">

Как видите, значения свойства font-size отличаются от значений атрибута SIZE= тега < FONT> . Для относительного увеличения размера шрифта исполь зуется значение larger, для относительного уменьшения— smaller. Кроме того, можно, во первых, указывать процентное изменение величины шрифта, например font-size: 120%;, либо его абсолютную величину. Для этого можно использовать либо значения xx-small, x-small, small, medium, large, x-large и xx-large, либо просто указать величину шрифта в пикселах — font-size: 18px; или в других единицах.

Кроме того, в нашем блоке присутствует тег <В> , также относящийся к оформлению, хотя почему-то и не отмененный в HTML 4.0. В CSS ему соответствует свойство font-weight: bold;. Однако мы не можем написать вместо

<В>Сергей Сергеев</В> следующее:

<DIV STYLE="font-weight: bold;">Сергей CepreeB</DIV>

поскольку в этом случае следующий текст будет перенесен на новую строку. Поэтому вместо тега <DIV> здесь следует использовать тег <SPAN> :

<SPAN STYLE="font-weight: bold;">Сергей Сергеев</SPAN>

Этот тег, кстати, бессмысленно применять без атрибутов, поскольку тогда вообще не будет никакого эффекта. Как правило, он применяется именно с атрибутом STYLE= (либо с атрибутами CLASS=, ID=, LANG= или обработчиками событий, о которых речь пойдет ниже).

Свойство font-weight (“жирность” шрифта), кстати, может принимать не только значения bold (полужирный) и normal (обычный), но и любое числовое значение от 100 до 900 (правда, имеют смысл только значения, кратные 100) — то есть, от самого тонкого до самого жирного шрифта. При этом значение 400 — это то же самое, что normal, a 700 — то же, что bold. Можно также употреблять относительные значения bolder и lighter.

Пойдем далее. После этого текстового блока у нас на веб-странице была горизонтальная линия <HR > с отмененным атрибутом W1DTH=, вместо которого следует использовать стилевое свойство width:

<HR STYLE="width: 75%;">

Кроме того, если помните, для организации вертикального отступа между текстом и горизонтальной чертой мы использовали не очень красивую конструкцию <BR>&nbsp; . В CSS имеется свойство margin, с помощью кото рого можно регулировать отступы (“поля”) со всех сторон элемента; а для индивидуальной регулировки отступов с каждой стороны можно исполь зовать свойства margin-top (отступ сверху), margin-bottom (отступ снизу), margin- left (отступ слева) и margin-right (отступ справа). Поскольку мы намеревались удалить горизонтальную черту от текста на расстояние, примерно равное одной строке, давайте напишем так:

<HR STYLE="margin-top: 24px; width: 75%;">

Интервал, определенный свойством margin-top, составляет 24 пиксела.

Далее центрируем заголовки рассказов с помощью уже знакомого нам свойства text-align. Но у нас есть еще подзаголовки, выделенные курсивом:

<I>сказка</I>

Поскольку тег <I> тоже относится к оформлению (хоть и не отменен), заме ним его стилевым свойством font-style: italic;, применив уже знакомый тег <SPAN>:

<SPAN STYLE="font-style: italic;">сказка</SPAN>

Кроме значений normal (обычный) и italic (курсив) это свойство может при нимать значение oblique (наклонный шрифт). Различие между наклонным шрифтом и курсивом состоит в том, что буквы курсива имеют иное начер тание. Правда, при использовании определенных шрифтов большинство броузеров пока что “халтурят” — используют курсив, если нет готового варианта наклонного шрифта.

Стилевое позиционирование

Теперь исправим конструкцию для эпиграфа:

<Р ALIGN="right"XFONT SIZE="-l">Hy, погоди!.. <BR>

<I>(Из мультфильма )</I>

</FONT></P>

Вместо атрибута ALIGN=, а также тегов <FONT> и <I> применим уже знакомые конструкции:

<Р STYLE="text-align: right; font-size: smaller; ">Hy, погоди!.. <BR><SPAN STYLE="font-style: italic; "> (Из мультфильма) </SPAN></P>

Кстати говоря, на самом деле и эта конструкция, и та, что была в старом варианте, не совсем подходит для эпиграфа. Удачно, что эпиграф у нас короткий. А что бы было, если он был бы немного длиннее, например таким:

<Р STYLE="text-align: right; font-size: smaller;">&laquo;Ну, погоди!..&raquo; &mdash; что есть мочи закричал Волк, стремительно падая вниз с обрывком веревки в лапе прямо на милицейский мотоцикл, который как раз в этот момент проезжал по дороге. Через мгновение мотоцикл уже увозил его куда-то вдаль.<BR><SPAN STYLE="font-style: italic;">(Из описания мультфильма) </SPAN></P>

Результат показан на рис. 4.1. Согласитесь, что это больше похоже не на эпиграф, а на какой-то вводный текст, потому что эпиграф должен оста ваться в правой части экрана. В старом варианте веб-страницы с этой про блемой было бы трудно справиться (пришлось бы либо рисовать невидимую таблицу, либо вручную разбивать текст эпиграфа тегами <BR> , что привело бы к различным результатам при просмотре в окнах разного размера). А при использовании CSS можно просто использовать такие свойства блока, как width и height (ширина и высота). Второе из них нам сейчас не нужно, а вот свойство width как раз пригодится:

<DIV STYLE="text-align: right;"> <P STYLE="text-align: justify; font-size: smaller; width: 35%;">

&laquo;Hy, погоди!..&raquo; &mdash; что есть мочи закричал Волк, стремительно падая вниз с обрывком веревки в лапе прямо на милицейский мотоцикл, который как раз в этот момент проезжал по дороге. Через мгновение мотоцикл уже увозил его куда-то вдаль.<BR>

<SPAN STYLE="font-style: italic;">(Из описания мультфильма)</SPAN>

</DIV>

Результат показан на рис. 4.2. Давайте с ним разберемся. Как видно из вышеприведенного кода, просто добавить свойство width: 35%; недоста точно. Действительно, тогда текст блока был бы выровнен по правому краю, но это выравнивание происходило бы внутри блока, а сам блок шириной 35% от полной ширины окна располагался бы слева. Поэтому весь блок, описанный тегом <Р> , пришлось заключить во внешний блок <DIV> , а уже в нем установить выравнивание по правому краю (text-align:right;). Ну, а раз уж выравнивание по правому краю взял на себя внешний блок, внутри текстового блока для лучшего восприятия мы выровняли текст но обоим краям (text-align: justify;).

Рис. 4.1. Длинный эпиграф при таком, оформлении становится не похожим, на эпиграф

Рис. 4.2. Выравнивание эпиграфа с помощью вложенных блоков

Все бы хорошо, однако подпись под эпиграфом хорошо бы выровнять по правому краю (хотя, поскольку она занимает почти всю строку, это не очень заметно), как на рис. 4.3. Но поскольку тег <SPAN> “не понимает” отдельного выравнивания, придется эту подпись также заключить в блок <DIV> или <Р>.

Рис. 4.3. Выравнивание подписи под эпиграфом

милицейский мотоцикл, который как раз в этот момент проезжал по дороге. Через мгновение мотоцикл уже увозил его куда-то вдаль.

</Р>

<Р STYLE="text-align: right; font-size: smaller; width: 35%; font-style: italic; position: relative; top:-18px;">

(Из описания мультфильма) </Р> </DIV>

Конечно, последняя конструкция выглядит несколько искусственной — собственно говоря, использованный здесь метод в данном случае напоминает известное выражение “Из пушки по воробьям”. Зато мы на этом примере сможем познакомиться с позиционированием объектов.

Обратите внимание на свойство position. Оно задает тип позиционирования — относительный или абсолютный. В данном случае определено относительное позиционирование (relative), то есть отсчет ведется от той позиции, которую должен был бы занимать этот элемент, если бы позиционирование не было задано. А абсолютное (absolute) позиционирование означает, что отсчет ведется от верхнего левого угла окна броузера (точнее, его рабочей области). Еще у этого свойства может быть значение static, означающее, что элемент не позиционируется индивидуально, и значение fixed (фиксированная позиция — элемент позиционируется абсолютно и не прокручивается вместе с остальным содержимым страницы), которое, однако, поддерживается пока только шестой версией Netscape.

Со свойством position тесно связаны еще два свойства — top и left, которые задают позицию верхнего левого угла элемента соответственно по верти кали и горизонтали. Чем больше значение top, тем ниже расположен эле мент, и, соответственно, чем больше значение left, тем элемент правее. В данном случае, для того чтобы приподнять текст примерно на высоту одной строки, нам пришлось написать: top: -18px;.

Ну, ладно, мы ведь договаривались пока что не менять ничего на страничке, поэтому вернемся к нашему короткому тексту, однако все равно приме ним к нему вышеуказанную конструкцию (со вложенными блоками <DlV>). Между прочим, даже с коротким текстом это все равно получается краси вее, чем раньше. Только заменим значение width на 130 точек (вместо процентного обозначения), а то при очень большом разрешении экрана короткий текст слишком сильно оторвется от подписи.

Абзацный отступ

Далее, в основном тексте рассказов у нас были абзацные отступы, сделанные с помощью серии неразрывных пробелов (&nbsp;) — способ не самый изящный. С помощью стилевого свойства text-indent можно определить абзацный отступ в любых единицах. Правда, придется отказаться от деления на абзацы с помощью тега <BR>, поскольку он “не поймет” указаний сделать отступ. Можно делить текст на абзацы “официальным” способом — <Р> , однако, чтобы избежать пропуска строки, мы воспользуемся тегом <DIV> :

<DIV STYLE="text-align: justify; text-indent: 2em;">

Здесь мы определили абзацный отступ, равный двум символам максимальной ширины в данном шрифте.

После текста рассказа все повторяется — та же горизонтальная линия, для которой мы укажем отступ сверху, опять заголовок, эпиграф и текст. Посмотрим, что получается в целом:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТIТLЕ>Домашняя страница Сергея Сергеева.</TITLE>

</HEAD>

<BODY
STYLE="background-color: #BABAAO; color:
rgb(29,29,24);" LINK="#634438"
VLINK="#634438" ALINK="Black" >

<H1 STYLE="text-align: center;">Домашняя страница Сергея Сергеева</Н1>

<DIV STYLE="text-align: center;">

<A HREF="#skazka">CKА3KА &laquo;Иван-царевич и серый зaяц&raquo;</A>&nbsp;

<A HREF="#rasskaz">PАССKА3 &laquo;МОЛОТОК&raquo;</A>

</DIV>

<BR>

<DIV STYLE="font-size: larger;">

<SPAN STYLE="font-weight: bold;,>Сергей Сергеев</SPAN> &mdash; писатель-авангардист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.<ВR><ВR>

Некоторые его рассказы вы можете прочитать прямо здесь. </DIV>

<HR STYLE="margin-top: 24px; width: 75%;">

<Н2 STYLE="text-align: center;"XA NAME="skazka">ИBAH-ЦAPEBИЧ И СЕРЫЙ ЗАЯЦ</А><ВR>

<SPAN STYLE="font-style: italic; ">CKА3KА</SPAN></H2> <DIV STYLE”"text-align: right;">

<DIV STYLE="text-align: justify; font-size: smaller; width: 130;">

Ну, погоди!..

<DIV STYLE="font-style: italic; text-align: right;">(Из мультфильма)</DIV>

</DIV> </DIV>

<BR>

<DIV STYLE="text-align: justify; text-indent: 2ет;">Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный. Однако тоскливо было у него на душе - как встанет утром с постели царской, так и начнет горевать, и горюет до вечера. </DIV>

<DIV STYLE="text-align: justify; text-indent: 2em;"> Долго ли, коротко ли, ...</DIV>

<DIV STYLE="text-align: justify; text-indent: 2em;"> ...И они жили долго и счастливо и умерли в один день.</DIV>

<HR STYLE="margin-top: 24px; width: 75%;">

<Н2 STYLE="text-align: center;"><A NAME="rasskaz">МОЛОТОК</A> <BR>

<SPAN STYLE="font-style: italic; ">paccкaз</SPAN>

</H2> <DIV STYLE="text-align: right;">

<DIV STYLE="text-align: justify; font-size: smaller; width: 130;">

Мы кузнецы, и дух наш молод.

<DIV STYLE="font-style: italic; text-align: right;">(Из песни) </DIV>

</DIV>

</DIV>

<BR>

<DIV STYLE="text-align: justify; text-indent: 2ет;">Это случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа) </DIV>

</BODY>

</HTML>

Результат показан на рис. 4.4. Вы можете заметить, что он практически не отличим от веб-страницы, представленной на рис. 2.8, если не считать немного “исправленных” эпиграфов и абзацных отступов.

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


4.2

4.2. Определение стилей в специальной таблице

Читая предыдущий раздел, некоторые, скорее всего, несколько раз поду мали: “Ну и где же здесь обещанное удобство? Неужели удобнее написать <SPAN STYLE="text-style: italic;">, чем просто <I>?”

Рис. 4.4. Веб-страница написанная с элементарным применением CSS

Все верно, в некоторых случаях Сев-запись действительно немного длиннее, но мы и не утверждали, что теперь нужно использовать только CSS, ~ в некоторых случаях можно воспользоваться и старыми тегами, ничего в этом предосудительного нет. Однако с помощью CSS мы имеем, во-первых, гораздо более широкие возможности, а во-вторых, получаем удобство работы над собственно стилями. В предыдущем разделе вы это удобство почувствовать не могли, поскольку в учебных целях мы записывали все свойства стилей как значения атрибута STYLE=. Этот способ широко применяется, но лишь в тех случаях, когда нужно применить какой-либо стиль к отдельно взятому фрагменту. А в большинстве случаев используют так называемые таблицы, стилей.

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

Стили элементов

Таблица стилей обычно располагается в заголовке HTML-документа, в разделе <HEAD> . Она занимает место между тегами <STYLE> и </STYLE> . Синтаксис таблицы стилей таков. Вы пишете имя элемента HTML, для которого определяете стиль, а после него следует блок определения стиля, заключенный в фигурные скобки. Например, в нашем примере можно написать так:

<STYLE> BODY { background-color: #ВАВААО; color: rgb(29,29,24); }

</STYLE>

Пробелы здесь не имеют никакого значения, так же, как и переводы строк. После этого в самом тексте HTML-документа достаточно указать тег <BODY> , и к нему автоматически будут применены данные цвета фона и текста.

Пока что мы вроде бы не получили никакой видимой экономии, хотя скоро вы увидите, что имеет смысл располагать стилевые свойства <BODY> именно в таблице стилей. Чтобы продемонстрировать экономию, пойдем дальше. В нашем примере мы три раза выравнивали заголовки по центру (еще хорошо, что три, а не пятьдесят шесть). Вместо этого можно просто написать в таб лице стилей:

Н1,Н2 { text-align: center; }

и после этого просто указывать в документе теги <Н1 > или <Н2> , содержи мое которых будет автоматически центрироваться. Обратите внимание на то, что в таблице стилей, чтобы определить стиль сразу для нескольких элементов, мы перечислили их через запятую.

Если вы помните, у нас еще оставались в теге <BODY> три “отмененных” атрибута: LINK=, ALINK= и VLINK=. Вместо них рекомендуется определить стили для различных псевдоклассов элемента <А>. Это делается так:

A:link,A:visited { color: #634438; } A:active { color: black; }

Как видите, для элемента <А> определены три псевдокласса (имена кото рых отделяются двоеточием): link — для гиперссылок, visited — для посе щенных гиперссылок и active — для активных. Кроме того, во второй версии CSS (CSS Level 2) для тега <А> определены еще псевдоклассы hover (гиперссылка, над которой находится указатель мыши) и focus (выбран

ная гиперссылка). Однако в броузере Internet Explorer версии 5 поддерживается только первый из них. Например, если написать

A:hover { color: white; }

то при наведении указателя мыши на ссылку она будет подсвечиваться белым цветом. Это уже похоже на динамическое взаимодействие с пользователем!'

Далее, в нашем примере мы два раза определяли одинаковый стиль для горизонтальной линии. Проще, конечно, написать в таблице стилей:

HR { margin-top: 24px; width: 75%; }

и потом в текст документа вставлять только тег <HR> , и тогда, если не указано иное, линия получится такой, какой нужно.

Стили классов

Все это хорошо, конечно, но как быть дальше? Ведь в тексте нашего примера несколько раз (в данном случае два, но могло бы быть и гораздо больше!) определяется один и тот же стиль для текста эпиграфа, другой стиль для основного текста и третий для подписи к эпиграфу... Хорошо бы тоже определить их в таблице стилей, однако в нашем HTML--документе все они расположены внутри элементов <DIV> , поэтому надо определить несколько различных стилей для одного элемента. Оказывается, это тоже можно сделать! Для этого, правда, придется использовать несколько более длинную запись, однако это все равно удобнее и короче, чем всякий раз определять атрибут STYLE= или задавать другие атрибуты.

Итак, у нас должно быть три различных стилевых варианта для элемента <DIV> . В CSS они называются классами. Чтобы отличить эти элементы друг от друга, у них придется установить атрибут CLASS=, приблизительно так:

<DIV
CLASS="epig">...</DIV> <DIV
CLASS="pdps">...</DIV> <DIV
CLASS="ab">...</DIV>

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

DIV.epig { text-align: justify; font-size: smaller; width: 130; }

DIV.pdps { font-style: italic;

text-align: right; }

DIV.ab { text-align: justify;

text-indent: 2em; }

Между прочим, другие элементы (причем практически все) также могут иметь атрибут CU\SS=. Если надо, чтобы определение класса было доступно всем элементам, его можно определить так:

pdps { font-style: italic;

text-align: right; }

То есть, при определении не указывается имя конкретного элемента HTML, а указывается только имя класса, которое в любом случае начинается с точки (но только в таблице стилей, а при обращении к классу в тексте документа точка не ставится). В данном примере мы определяли классы только для элемента <DIV>. Более того, в таком определении предполагается (то есть мы как бы помним), что элемент класса pdps будет вложен в элемент класса epig. Хотя, с другой стороны, наше определение pdps годится не только для подписи под эпиграфом, но и для любой другой, если она вдруг потребуется.

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

#соо1 { color: white; background-color: black; )

Тогда элемент по имени cool (например <DIV ID="cool"> ) будет наделен указанными свойствами (в данном случае белым цветом символов на черном фоне). Только не забывайте, что в каждом HTML-документе каждый идентификатор ID= должен быть уникальным, то есть не может быть двух и более элементов с одинаковым значением атрибута ID=.

Ладно, это мы немного отвлеклись, так что давайте посмотрим на новый вариант странички Сергея Сергеева целиком.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТITLE>Домашняя страница Сергея Cepreeвa</TITLE>

<STYLE>

<!--

BODY { background-color: #BABAAO;

color: rgb(29,29,24);

}

H1,H2 { text-align: center;

} A:link,A:visited { color: #634438;

} A:active { color: black;

} HR { margin-top: 24px;

width: 75%; ) DIV.epig { text-align: justify;

font-size: smaller;

width: 130; } DIV.pdps { font-style: 'italic;

text-align: right;

} DIV.ab { text-align: justify;

text-indent: 2em; }

-->

</STYLE>

</HEAD>

<BODY> <Н1>Домашняя страница Сергея Сергеева</Н1>

<DIV STYLE="text-align: center;"><A HREF="#skazka">CKА3KА &1аquо;Иван-царевич и серый зaяц&raquo;</A>&nbsp;

<А HREF="#rasskaz">PaccKa3 &laquo;МОЛОТОK&raquo;</A>

</DIV>

<BR>

<DIV STYLE="font-size: larger;">

<SPAN STYLE="font-weight:

bold;">Сергей Сергеев</SPAN> Smdash; писатель-авангардист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.<ВR>

<ВR>

Некоторые его рассказы вы можете прочитать прямо здесь.</DIV>

<HR>

<Н2><А NAME="skazka">ИBAH-ЦAPEВИЧ И СЕРЫЙ ЗАЯЦ</А><ВR>

<SPAN STYLE="font-style: italic; ">CKА3KА</SPAN></H2>

<DIV STYLE="text-align: right ;">

<DIV CLASS="epig">

Ну, погоди!..

<DIV CLASS="pdps">(Из мультфильма)</DIV>

</DIV>

</DIV> <BR>

<DIV CLASS="аЬ">Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный. Однако тоскливо было у него на душе - как встанет утром с постели царской, так и начнет горевать, и горюет до вечера.</DIV>

<DIV CLASS="ab">Дoлгo ли, коротко ли, ...</DIV>

<DIV CLASS="ab">...И они жили долго и счастливо и умерли в один день.</DIV>

<HR>

<Н2><А NAME="rasskaz">МОЛOTOK</A>

<BR>

<SPAN STYLE="font-style: italic; ">paccкaз</SPAN>

</H2>

<DIV STYLE="text-align: right;">

<DIV CLASS="epig"> Мы кузнецы, и дух наш молод. <DIV CLASS="pdps">(Из песни)</DIV>

</DIV>

</DIV>

<BR>

<DIV CLASS="ab">Этo случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа) </DIV>

</BODY>

</HTML>

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

Наверное, вы обратили внимание на странные сочетания <!-- и --> , которые появились в нашем примере около тегов <STYLE> . Вообще говоря, в такие символьные сочетания (это, кстати, тоже теги) в HTML-докумен-тах заключают комментарии. То есть все, что находится между этими тегами, игнорируется броузером. Но в данном случае мы пользуемся тем, что внутри STYLE -блока действуют законы синтаксиса не HTML, a CSS. Так что те броузеры, которые “понимают” тег <STYLE> и, следовательно, CSS, “поймут” и то, что в данном случае это не символы комментария, и проинтерпретируют таблицу стилей, как положено. А те броузеры (в основном, старые), которые CSS не понимают, воспримут содержимое таблицы стилей как комментарий. (Если не поставить теги комментариев, то эти броузеры, проигнорировав тег <STYLE> как непонятный им, скорее всего станут выводить на экран все содержимое таблицы стилей.) Таким же образом мы будем “обманывать” старые броузеры при использовании тега <SCRIPT>.

Внешние стилевые таблицы

Еще одно замечательное свойство стилевых таблиц заключается в том, что с помощью одной таблицы, находящейся в отдельной файле, можно задавать стили для целого набора веб-страниц. Это, кстати, очень важно при разработке больших сайтов, поскольку, во-первых, способствует сохра нению единства стиля, а во-вторых, предоставляет возможность быстро изменить что-либо сразу во многих файлах проекта. Для этого следует просто написать всю таблицу стилей (без тегов <STYLE> и </STYLE> ) в отдельном файле с расширением .css, а затем “подключить” ее во всех HTML- документах, которые должны ее использовать. Например, если файл таблицы стилей называется mainstyle.css, то в раздел <HEAD> каждого из использующих ее HTML-документов, нужно вставить такую строку:

<LINK REL="Stylesheet" HREF="mainstyle.css" TYPE="text/css">

Атрибут TYPE= указывать не обязательно, но лучше это сделать (кстати, это можно делать и в теге <STYLE> ). Во-первых, это признак хорошего тона, а потом мало ли что — вдруг пользователю, к примеру, попадется какой-нибудь сумасшедший броузер, использующий для стилевых таблиц по умолчанию не CSS, а, допустим, JASS.

Есть и другой способ “подключения” стилевой таблицы из внешнего файла — директива @import. Она употребляется следующим образом:

<STYLE TYPE="text/css"> @import url (mainstyle.css) ; </STYLE>

Как видите, эта директива должна находится между тегами <STYLE> и </STYLE> , поскольку она не является элементом языка HTML (как тег <LINK> ). Ее использование менее предпочтительно, поскольку броузеры могут интерпретировать ее по-разному.


4.3

4.3. Обзор других возможностей стилевых таблиц

В примерах предыдущих двух разделов мы кратко продемонстрировали способы применения стилевых таблиц CSS и их удобство. Однако, помимо упорядочивания стилевой информации, таблицы стилей CSS открывают для создателя веб-страниц и многие новые возможности, которые недоступны в стандартном языке HTML. Правда, к сожалению, употребляя новые возможности CSS, нужно четко представлять себе, что не все броузеры смогут их проинтерпретировать правильно. На сегодняшний день существует два “абстрактных” стандарта CSS — так называемый стандарт CSS1 и более новый стандарт CSS2. Реальные броузеры по-разному поддерживают (или не поддерживают) их. Некоторые свойства стилей, описанные в CSS1 и, особенно, CSS2, до сих пор не получили поддержки в ряде броузеров, а некоторые не поддерживаются вообще. И, наоборот, существуют броузерные расширения, не описанные в стандартах CSS1/CSS2.

Однако не надо этого пугаться: все равно новые возможности использовать стоит, просто надо проверять результаты своей работы в разных бро-узерах и сравнивать их. Впрочем, это относится даже не столько к CSS, сколько к динамическим страницам, создаваемым с использованием JavaScript Итак, давайте познакомимся с некоторыми новыми возможностями CSS. Замечательно, что многие стилевые свойства здесь можно применять практически ко всем элементам. Например, цвет фона (свойство background-color), который мы в предыдущих примерах определяли для элемента <BODY> , может с таким же успехом задаваться и для отдельных текстовых блоков и даже слов. Более того, все элементы могут иметь свой фоновый рисунок (свойство background-image).

Практически для всех элементов можно теперь также определить поля (свойство margin), рамки различного вида и толщины (свойство border), и отступы (свойство padding). Различие между полем и отступом заключается в том, что отступ находится внутри рамки элемента, а поле — вне нее. Свойства полей, рамок и отступов могут задаваться индивидуально для каждой из сторон блока. Более гибко можно выбирать свойства шрифта: его начертание, размер, степень “жирности”, гарнитуру и оформление (это, соответственно, свойства: font-stlye, font-size, font-weight, font-family, text-decoration). Интересное свойство text-decoration позволяет, например, не только зачеркнуть или подчеркнуть текст, но и сделать его подчеркнутым (text-decoration: overline) или даже мигающим (text-decoration: blink). Правда, значение blink поддерживается пока только в Netscapel и Opera 4. Можно несколько “оживить заголовки с помощью свойства font-variant: small-caps. Правда, пока что это работает только в Netscape 6, a Internet Explorer просто преобра зует строчные буквы в прописные, а прописные не увеличивает.

Чтобы было интереснее, давайте рассмотрим некоторые свойства на кон кретном примере. Помните веб-страничку гипотетической фирмы “Лентяй” из главы 2? Сейчас мы попробуем взять ее за основу и улучшить оформление.

Размещение блоков текста

Вообще-то “Лентяй”, хоть и гипотетическая, но все же фирма, поэтому на ее сайте должны присутствовать несколько разделов, без которых корпоративный сайт уже не воспринимается, типа “О компании”, “Услуги” (или “Продукция”), “Цены”, “Новости” и прочие. Поэтому мы тоже снаб дим для начала эту страничку блоком соответствующих гиперссылок:

<DIV CLASS="lnk">УСЛУГИ</DIV> <DIV CLASS="lnk">

<A HREF="prices.html">ЦЕНЫ</A></DIV>

<DIV CLASS="lnk"><A HREF="forml .html">ФОРМА 3AKA3A</A></DIV>

<DIV CLASS="lnk"><A HREF="history.html">ИСТОРИЯ КОМПАНИИ</А> </DIV>

<DIV CLASS="lnk"><A HREF="guestbook.html">KHИГА OT3ЫBOB</A></DIV>

Как можно организовывать загрузку разделов.

Обратите внимание на то, что для списка ссылок мы определили класс Ink. Пока что определения свойств этого класса у нас нет, но ясно, что блок ссылок должен выглядеть как-то не так, как все остальное. Поскольку мы уже вроде бы находимся в разделе “Услуги” (см. содержание стра нички), гиперссылка на него отсутствует.

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

Рис. 4.5. Добавим на страничку блок гиперссылок

.hdr

{ position: absolute; left: 50px;

top: 10рх; } Мы немного отступили от края странички, хотя можно было указать,

конечно, и нулевые значения left и top. Заодно можно сразу указать свойство text-align: center;

для центрирования нашего заголовка. В тексте документа напишем:

<DIV CLASS="hdr">ФИРМА&nbsp;ЛЕНТЯЙ</DIV>

На всякий случай мы здесь используем неразрывный пробел вместо обычного, чтобы избежать переноса слова “Лентяй” на следующую строку. Затем определим класс Ift для левой части странички:

.ift { position: absolute; font-size: meduim; left: 10рх; top: 160px; width: 550px; height: 400px; overflow: auto; }

Здесь нужно немного пояснить. Во-первых, мы определили отступ от верх него края в 160 пикселов, чтобы оставить место для заголовка. Кроме того, свойство width определяет ширину этого блока так, чтобы оставить немного места справа для блока гиперссылок. Мы могли не определять свойство height, однако с его помощью можно “вогнать” всю информацию в преде лы экрана, а ту, что не поместится, доставать с помощью дополнительной полосы прокрутки, определив для этого свойство overflow: auto. Тогда назва ние фирмы будет всегда оставаться в верхней части экрана. Можно также было определить свойство overflow: scroll;, и тогда дополнительная полоса прокрутки (для левого блока) была бы видна в любом случае. Значение auto заставляет броузер показывать ее только тогда, когда это необходимо, то есть, когда есть информация, не помещающаяся в пределах блока.

В тексте документа, соответственно, заключим всю основную информацию в блок класса Ift:

<DIV CLASS="lft"> Наша фирма предоставляет следующие услуги: <UL>

<li>Бытовые услуги

И, наконец, определим класс rght для блока гиперссылок, который будет располагаться справа:

.rght { position: absolute; font-size: large; left: 565px;

top: 160px;

width: 160px; height: 400px; }

Поскольку гиперссылки должны быть хорошо заметны на фоне всего остального, мы сразу определяем для них более крупный шрифт (font-size: large;). Значение свойства top должно быть таким же, как и у класса Ift, чтобы оба блока расположились на одинаковой высоте. Значение left выбрано таким, чтобы слева осталось достаточно места для информационного блока. Теперь присвоим класс rght нашему блоку гиперссылок:

<DIV CLASS="rght">

<DIV CLASS="lnk">УСЛУГИ</DIV>

<DIV CLASS="lnk"><A HREF="prices.html">ЦЕНЫ</A></DIV>

<DIV CLASS="lnk"><A HREF="forml.html">ФОPMA 3AKA3A</A></DIV>

<DIV CLASS="lnk"><A HREF="history.html">ИСТОРИЯ КОМПАНИИ</А> </DIV>

<DIV CLASS="lnk"><A HREF="guestbook .html">KHИГА OT3ЫBOB</A></DIV>

</DIV>

Добавление фонового рисунка

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

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

background-position: right;

Однако посмотрите на результат (рис. 4.7). Фоновый рисунок действительно выровнен по правому краю, но он повторяется во все стороны, а нам это не нужно. Чтобы он повторялся только по вертикали, нужно добавить в свой ства BODY еще такую строку:

background-repeat: repeat-y; i

Рис. 4.6. Позиционирование блока гиперссылок

Вот теперь получилось то, что нужно. Кстати, можно заставить фоновый рисунок повторяться только по горизонтали (repeat-x) или вообще не повторяться (no-repeat). В этом случае можно указать любое значение свойства background-position в процентах, пикселах или иных единицах.

Оформление текста

Теперь давайте займемся информационным блоком. Чтобы информация хорошо читалась и воспринималась, он не должен особо страдать излишествами, однако, чтобы выделить заголовки списков, их можно написать более крупно и шрифтом другого начертания. Для этого определим соответствующий класс: .bigger { font-size: larger; font-family: sans-serif; }а в тексте документа применим его:

<DIV CLASS="bigger">Haшa фирма предоставляет следующие услуги:</DIV>

Как вы уже, наверное, поняли, свойство font-family определяет гарнитуру шрифта. Значение sans-serif соответствует шрифтам, не имеющим засечек. По умолчанию обычно определен шрифт serif (с засечками, обычно это Times New Roman).

Кроме того, воспользуемся уже знакомым нам стилевым свойством list- style-image для использования графических маркеров списка. Поскольку список у нас трехуровневый, то логично создать три маркера разных цветов. Как применить графические маркеры, вы уже знаете:

<UL STYLE="list-style-iiriage: url ("Images/markeri .gif ) ; ">

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

Далее будем немного изменять вид гиперссылки при наведении на нее мыши. Здесь можно придумать различные варианты. В нашем примере мы решили изменять шрифт на полужирный и убирать подчеркивание при наведении мыши:

A:hover { font-weight: bold; text-decoration: none; } Все эти свойства вам уже знакомы. Давайте взглянем, что у нас получается (рис. 4.7).

Декоративное оформление текста

Для информационного блока оформление уже вполне закончено. Теперь займемся блоком гиперссылок. Вспомним, что мы для этого даже загото вили класс Ink. Чтобы наши разделы были хорошо заметны, давайте их обведем рамками:

.Ink { border-width: thick; border-style: ridge; border-color: #319CFF; color: red; text-align: center; } Чтобы рамка вообще отобразилась, необходимо определить свойство border-style (дело в том, что по умолчанию его значение — none, то есть рамки нет). Здесь мы можем выбрать вид рамки из возможных: solid (обычная), double (двойная), groove (вогнутая с обеих сторон), ridge (выпуклая с обеих сторон), inset (вогнутая), outset (выпуклая), dotted (точечная) и dashed (пунктир-

Рис. 4.7. Применение стилей к основной части странички

ная). Последние два значения, правда, пока воспроизводятся только в бро-узере Netscape 6. Мы выбрали значение ridge. Чтобы рамка не терялась на фоне больших букв, зададим свойство border-width: thick; (толстая рамка; еще можно указывать значения thin — тонкая и medium — средняя, а также задавать толщину в любых единицах). С помощью свойства border-color установим цвет рамки, по оттенку сочетающийся с фоном.

Поскольку в одном из обозначенных разделов мы всегда будем находиться, его название не будет являться гиперссылкой. Для него мы определили свойство color: red; (красный цвет текста). У гиперссылок, как вы помните, свой цвет.

Однако при этом придется сменить цвет гиперссылок на более светлый. Но будьте внимательны! Цвет гиперссылок нужно сменить только для класса Ink, потому что в других местах гиперссылки расположены на свет лом фоне, и их уже нельзя осветлять, иначе их не будет видно. Поэтому не (нужно переопределять свойства элемента <А> целиком. Нужно переопре делить некоторые его свойства только внутри класса Ink:

.Ink A{ text-decoration: none; color: white;

Такая запись делает как раз то, что нам нужно: в классе Ink для элемента <А> определяются некоторые новые свойства, а остальные остаются такими же, как и у всех элементов <А>. Заодно мы использовали свойство text- decoration: none;, чтобы снять подчеркивание с гиперссылок в этом блоке — в таком “кнопочном” оформлении оно неуместно.

Теперь все вроде бы нормально, однако одна из кнопок “вылезает” за пределы отведенного пространства (из-за слова “компании”). Можно, конечно, это пространство увеличить, но давайте лучше попытаемся немного “ужать” это слово. Есть такое стилевое свойство letter-spacing, которое задает дополнительное расстояние между буквами. Если это расстояние задать отрицательным, буквы расположатся теснее обычного:

<DIV
CLASS="lnk"><A
НRЕF="histогу.html">ИСТОРИЯ <SPAN
STYLE="letter-spacing:
-3рх;">KOMПAHИИ</SPAN></A></DIV>

Оформление заголовка

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

width: 90%; height: 100рх;

Эти значения мы определяем для класса hdr. Значение height выбираем с таким расчетом, чтобы осталось еще немного пространства сверху от остальных блоков нашей веб-странички. Далее для заголовка лучше назначить шрифт покрупнее:

font-size: 6Орх;

Кроме того, будет лучше, если шрифт заголовка будет контрастен относительно всех остальных шрифтов. Выберем какую-нибудь необычную гарнитуру:

font-family: OdessaScriptFWF;

Однако, указывая в явном виде название гарнитуры шрифта, следует предусмотреть случай, когда на компьютере пользователя этого шрифта не окажется. Для этого можно определить (через запятую) еще несколько вариантов начертания шрифта в порядке убывания предпочтительности. Последним обязательно укажите начертание из стандартного набора (serif, sans-serif, cursive, fantasy, monospace). В данном случае нам нужен необычный шрифт, поэтому укажем значение fantasy:

font-family: OdessaScriptFWF, fantasy;

Теперь расставим буквы немного пошире с помощью уже знакомого нам свойства letter-spacing, а также определим высоту строки, равной высоте нашего блока:

letter-spacing: 0.05em; line-height: 100рх;

font-weight: 900;

Как видите, мы определили здесь максимально возможную жирность шрифта. Теперь определим цвет текста, сочетающийся с цветом фона:

color: #3163CE;

Далее, мы хотели нарисовать рамку вокруг заголовка. Определим ее свойства, используя сокращенную запись:

border: 10рх outset #003163;

В этой записи определены сразу три свойства: border-width, border-style и border-color. В некоторых случаях допустимо подобное объединение значений нескольких свойств в одну строку. Это можно написать быстрее, хотя и менее наглядно.

В принципе заголовок готов. Давайте только добавим к нему еще визуальный эффект с помощью свойства filter. Это работает, правда, только в броузере Internet Explorer и отсутствует в спецификациях CSS, однако смотрится очень красиво. Можно применить это свойство, например, так:

filter: shadow;

В результате наш блок будет отбрасывать тень. Существуют такие значения свойства filter, как dropshadow (другой тип тени), blur (размытие), wave (отражение в волне) и прочие.

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

Для полного завершения картины неплохо бы еще добавить какой-либо фоновый рисунок типа “водяного знака”, символизирующий профиль деятельности фирмы. Поскольку фирма называется “Лентяй”, возьмем за основу фотографию компании, занятой бездельем. Чтобы она стала похожа на “ водяной знак ”, вначале обработаем ее в графическом редакторе, например в Adobe Photoshop.

Исходное изображение сначала несколько размоем. В Adobe Photoshop это делается фильтром фильтр> Размытие > Сильное размытие (Filter > Blur > Blur More). Для усиления эффекта применим этот фильтр несколько раз подряд. Затем дайте команду Изображение > Настройка > Оттенок и насыщенность (Image > Adjust > Hue>Saturation). Здесь можно придать изображению оттенок, сходный с цветом фона. Затем необходимо уменьшить контрастность изображения, чтобы оно не отвлекало на себя слишком много внимания, и увеличить его яркость, поскольку у нас светлый фон: Изображение > Настройка > Яркость/Контраст (Image > Adjust > Brightness/Contrast). После этого обрежем изображение по контуру основного рисунка и сохраним в формате GIF с прозрачным фоном.

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

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

.logo { position: absolute; left: 150; top: 220; } Теперь присвоим этот класс нашему рисунку:

<IMG
CLASS="logo" SRC="Images/logo6.gif"
WIDTH="500" HEIGHT="346"
BORDER="0">

Действительно, при абсолютном (да и относительном) позиционировании блоки могут накладываться друг на друга, и тогда возникает проблема “третьего измерения” — какой из них окажется “выше”? Для решения этой проблемы придумали стилевое свойство z-index. Чем больше его значение, тем “выше” располагается блок при наложении.

Чтобы наш “водяной знак” не загораживал все остальное, определим для класса logo отрицательное значение z-index:

z-index: -5;

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitionai//EN"> <HTML>

<HEAD>

<TITLE>ФИРМА "ЛЕНТЯЙ"</ТIТLЕ>

<STYLE> BODY {

background-color: #D2FFFF;

color: #003737;
background-image: url("Images\grad2.jpg");
background-position: right; background-repeat: repeat-y;

} A:link,A:active,A:visited { color: #006A6A;

} A:hover { font-weight: bold; text-decoration: none;

}.hdr { position: absolute; left: 50px; top: 10рх; text-align: center; font-family: OdessaScriptFWF, fantasy, font-size: 60px; font-weight: 900; width: 90%; height: 100px; letter-spacing: 0.05em; line-height: 100px; filter: shadow; border: 10рх outset #003163; color: #3163CE;

} .rght {
position: absolute; font-size: large; left: 565px; top: 160px;
width: 160px; height: 400px; overflow-x: visible; }

.Ink { border-width: thick; border-style: ridge; margin: 10рх; padding: 5px; border-color: #319CFF; background-image: uri("Images/backlnki.jpg") ; color: red; text-align:center;

} .Ink A {
text-decoration: none; color: white; } .1ft { position: absolute;
font-size: meduim; left: 10рх; top: 160px; width: 550px;
height: 400px; overflow: auto; } .bigger { font-size: larger;
font-family: sans-serif; } .logo { position: absolute; left: 150;
top: 220; z-index: -5; }

</STYLE>

</HEAD>

<BODY>

<DIV CLASS="hdr">ФИРМА&nbsp;&1аquо;ЛЕНТЯЙ&raquо;</DIV>

<DIV CLASS="rght"> <DIV CLASS="lnk">УСЛУГИ</DIV>

<DIV CLASS="lnk"><A HREF="prices.html">ЦЕНЫ</A></DIV>

<DIV CLASS="lnk"><A HREF="forml.html">ФОРMA 3AKA3A</AX/DIV>

<DIV CLASS="lnk"><A HREF”"history.html">ИСТОРИЯ <SPAN STYLE="letter-spacing: -3px; ">КОМПАНИЯ</SPAN>

</A>

</DIV>

<DIV CLASS="lnk"><A HREF="guestbook.html">КНИГА ОТЗЫВОВ</А> </DIV>

</DIV> <DIV CLASS="lft"> <DIV CLASS="bigger">Haшa фирма предоставляет услуги:</DIV>

<UL STYLE=list-style-image: url('Images\markerl.gif);">

<LI>Бытовые услуги <UL STYLE="list-style-image: url('Images\rriarker2.gif');">

<LI>Вкручивание электрических лампочек <LI>Услуги по наведению чистоты <UL STYLE="list-style-image: url('Images\marker3.gif');"> <LI>Подметание пола <LI>Вынесение мусора из квартиры <LI>Мытье посуды </UL>

</UL> <LI>Приготовление пищи <LI Компьютерные услуги <UL STYLE="list-style-image: url('Images\marker2.gif');"> <LI>Дефрагментация жестких дисков

<LI>Переустановка Windows </UL> </UL>

<DIV CLASS="bigger">Чтобы воспользоваться услугами, следует: </DIV>

<OL> <LI> Зарегистрироваться (<А НRЕF="reg.htm1">здесь</А>)

<LI>Заполнить форму заказа (<А HREF="forml.htm1">здесь</А>)

<LI>Подтвердить заказ:

<OL TYPE="I">

<LI>Получив письмо с паролем, послать пустой ответ

<LI>Заполнить форму-подтверждение заказа

(<А НRЕF="form2.htm1">здесь</А>)

</OL> <LI>Приготовить деньги для оплаты услуг </OL> </DIV>

<IMG
CLASS="logo" SRC="Images/logo6.gif"
WIDTH="500" HEIGHT="346"
BORDER="0">

</BODY>

</HTML>

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

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


5

5. Использование звука на веб-странице

5.1. Добавление звукового оформления

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

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

Фоновая музыка

Для воспроизведения фоновой музыки проще всего применить тег <BGSOUND> . Правда, он работает только в броузерах Internet Explorer и Mosaic, зато очень удобен. Если написать так:

<BGSOUND SRC="beethl.mid" LOOP="-1" BALANCE”"-5000" VOLUME="0">

то на веб-странице в качестве фоновой музыки будет исполняться файл beeth.mid, который указан в атрибуте SRC=. Атрибут LOOP= нужен для того, чтобы определить, что делать, когда музыкальный фрагмент завершится. Значение LOOP="-1" или LOOP="infinite" означает, что музыкальный файл будет проигрываться от начала до конца бесконечное количество раз (пока пользователь не покинет веб-страницу). Значением атрибута LOOP= может быть положительное число, означающее количество повторов звукозаписи. Например, при LOOP="4" файл будет проигран четыре раза.

Для броузера Internet Explorer версии 4 (и более поздних) можно применять еще два атрибута: VOLUME= и BALANCE=. С помощью атрибута VOLUME= можно уменьшить громкость звучания. Именно уменьшить, поскольку | значение этого атрибута по умолчанию равно нулю, что соответствует максимальной громкости. Теоретически, предельное значение атрибута

VOLUME= равно -10 000, однако обычно в использовании значений менее -1000 особого смысла нет.

Атрибут BALANCE= задает смещение звука по панораме. Его значение равное “-10 000” соответствует крайнему левому положению, а “10 ООО” — крайнему правому. Значение по умолчанию равно нулю, что соответствует расположению звука по центру, в большинстве случаев является оптимальным решением.

Существует еще один атрибут тега <BGSOUND>, работающий только в броузере Mosaic. Это атрибут DELAY=, который определяет паузу перед нача лом звучания фонового музыкального файла. Интересно, что значение DELAY= нужно указывать в секундах (а не в миллисекундах, как обычно). Применение этого атрибута имеет смысл только для не больших аудиоклипов, поскольку обычно музыкальный файл все равно начинает звучать после некоторой задержки, так как загружается довольно долго, особенно если это файл формата WAVE или AIFF.

Звуковые объекты

Другой способ помещения музыкального объекта на страничку заключается в применении более универсального тега <OBJECT> . Вообще говоря, этот тег может использоваться не только для встраивания звуковых объектов. Он появился в свое время в Internet Explorer для встраивания объектов ActiveX/COM (что было альтернативой возможности запуска Java-апплетов в броузерах Netscape с помощью тега <APPLET> ). Если музыкальный объект размещен на веб-странице с помощью тега <OBJECT> , броузер в некоторых случаях может сообщить об отсутствии средств воспроизведения файлов такого типа. Иногда это вызывает удивление, так как те же файлы прекрасно воспроизводятся на том же компьютере, однако здесь требуется не любое средство воспроизведения, а только встроенное в данный броузер. В таких случаях необходимо доустановить модуль просмотра в броузер (может быть, предварительно загрузив его из Интернета).

Для помещения музыкального объекта на страничку используется такой синтаксис тега <OBJECT>:

<OBJECT DATA="SOUNDS/MyI')OLLY.mp3" TYPE="audio/wav">

</OBJECT>

Как видите, атрибут DATA= определяет файл — источник музыки, а атрибут TYPE= определяет его тип (формат). О форматах мы поговорим ниже.

Если при использовании тега <BGSOUND> музыка исполняется в качестве фона, то при использовании тега <OBJECT> объект можно наблюдать на экране, как правило, в виде встроенного проигрывателя с кнопками Пуск, Стоп и другими элементами управления. Поэтому для тега <OBJECT> возможно использование таких атрибутов, как ALIGN= (со значениями top, middle, bottom, left, right), WIDTH=, HEIGHT=, HSPACE=, VSPACE= и даже USEMAP=. Все эти атрибуты нам уже знакомы по тегу <IMG>. Кстати, с помощью тега <OBJECT> действительно можно вставлять в тексты веб-страниц графические объекты и видеоклипы. При этом список форматов существенно расширяется (например, можно просматривать картинки в форман тах TIFF и WMF), лишь бы только к броузеру был подключен соответствующий модуль просмотра. Кстати, можно вкладывать несколько элементов <OBJECT> друг в друга. Это приводит к следующему результату: если в броузере имеется средство просмотра внешнего объекта, будет отображен именно он, а если нет — броузер попытается отобразить внутренний объект, и т. д. Например, можно написать так:

<OBJECT DATA="MyClip.mpg" TYPE="video/x-mpeg">

<OBJECT DATA="MySound.aiff" TYPE="audio/x-aiff">

<OBJECT DATA="MyPicturel.tiff" TYPE="image/tiff">

<OBJECT DATA="MyPicture2.gif" TYPE="image/gif"> Здесь должен быть видеоклип... </OBJECT> </OBJECT> </OBJECT> </OBJECT>

В этом примере броузер сначала попытается воспроизвести видеоклип (файл в формате MPEG). Если это ему удастся, то все, что находится внутри данного тега, игнорируется, а если нет — броузер попытается воспроизвести музыкальный файл в формате АIFF. Если же он не найдет модуля вос произведения и для этого файла, он попытается отобразить рисунок в формате TIFF, а уж если и это не получится, то в формате GIF. При таком невероятном стечении обстоятельств, что броузеру и это не удастся сделать, на месте объекта будет просто отображен текст Здесь должен быть

видеоклип... И еще один момент. В теге <OBJECT> можно установить атрибут STANDBY=, значение которого (текстовая строка) будет отображаться на экране до тех пор, пока объект не загрузится целиком. Например, вполне целесообразно написать так:

<OBJECT DATA="sound.wav" TYPE="audio/wav" STANDBY="3arpyжаю звуковой объект, подождите немного...">

Если файл sound, wav имеет достаточно большой размер, пользователь уви дит на экране надпись о происходящей загрузке.

Звуковые гиперссылки

И наконец, еще один способ помещения музыки на веб-страницу заключается в простом создании гиперссылки на музыкальный файл (в атрибуте HREF=). Например, если написать

...А теперь послушайте <А HREF="mymusic.mid">музыкy</A>!

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

Форматы звуковых файлов

Итак, какие же форматы музыкальных файлов мы можем использовать? Прежде всего, это, конечно, звуковые форматы WAVE, AU та. AIFF. Эти форматы могут содержать собственно звук. Иногда они могут содержать также сжатые звуковые данные, однако оформленные в стандартном формате, причем для их воспроизведения в системе должны быть установлены соответствующие модули. В теге <OBJECT> формат WAVE обозначается как audio/wav, формат AU — как audio/basic и формат AIFF — как audio/x-aiff. Кроме того, существует звуковой формат Netscape Packed Audio, файлы которого имеют расширение .lа или .Ima. Он обозначается как audio/ nspaudio.

Звуковые файлы занимают обычно большой объем (даже в сжатом виде), и, соответственно, загружаются через Интернет слишком долго. Поэтому очень часто употребляют также музыкальные файлы в формате MIDI. MIDI-фацлы не содержат собственно звуковой информации. Они содержат только набор команд типа клавишу ДО первой октавы нажать через 2 секунды после начала, отпустить еще через 0.5 секунды (конечно, это очень примитивное описание MIDI-команды, но в целом дает представление о том, что это такое). Эти команды исполняются синтезатором, встроенным в звуковую карту пользователя (или внешним модулем, если таковой имеется). Поэтому качество звучания, услышанное пользователем, сильно зависит от имеющегося у него оборудования. Однако файлы, написанные для стандарта GM {General MIDI) обычно звучат очень похоже на всех синтезаторах, поддерживающих его, а его поддерживают практически все современные звуковые карты.

Поскольку набор MIDI-команд занимает намного меньший объем, чем звуковая информация, MIDI-файлы загружаются намного быстрее. Например, MIDI-файл длиной звучания 1 мин. обычно занимает от 10 до 30 Кбайт (в зависимости от темпа и количества нот), и, соответственно, время его загрузки составит приблизительно от 3 до 12 с при соединении через модем на скорости 28 800 бит/с. Звуковой же файл длиной 1 мин. будет иметь размер около 10 Мбайт в несжатом и приблизительно от 300 Кбайт до 2 Мбайт — в сжатом виде. Время его загрузки через то же соединение будет, соответственно, колебаться в пределах от 1 мин. 40 с. до 12-14 мин. Для загрузки в несжатом виде — около часа. Как видите, если продолжительность загрузки критична, то использование формата MIDI имеет неоспоримые преимущества.

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

Сжатие звуковых файлов

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

Наиболее популярны на сегодняшний день три формата сжатия звуковых файлов: RealAudio, MPEG 1 Layer 3 и TwinVQ.

Формат RealAudio был разработан фирмой RealNetworks. Это самый ран ний из форматов сжатия звукозаписи, и потому он наиболее распростра нен в Интернете. В настоящее время он поддерживает сжатие для потока (скорости загрузки) от 5 до 96 килобит в секунду. Низкие значения этого параметра (от 5 до 16 Кбит/с) предназначены для медленных модемов. Их предпочтительнее использовать лишь для речевых записей, поскольку при скорости потока 16 Кбит/с максимальная воспроизводимая частота звука не превышает 8 КГц, то есть при прослушивании пользователь практически не услышит высоких частот, а при более сильном сжатии (до 5 Кбит/с) о каком-то адекватном восприятии вообще говорить не приходится. Для сжатия музыки лучше использовать скорость потока не менее 32 Кбит/с, что дает вполне приемлемые результаты для монофрагментов.

Вы можете спросить, а почему это степень сжатия мы вдруг стали измерять в единицах величины потока (скорости загрузки)? На самом деле это имеет смысл! Дело в том, что главной проблемой использования звука в Интернете было то, что пользователь просто уставал ждать, пока загрузится большой файл — ведь воспроизведение его могло начинаться только по окончании полной загрузки. Компания RealNetworks предложила нов шество, называемое потоковым методом воспроизведения звуковых (а впоследствии и видео-) файлов. При использовании этого метода воспроизведение может начаться почти сразу же после начала загрузки файла. Пока одна часть файла загружается, другая уже воспроизводится!

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

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

Формат RealAudio

Файлы формата RealAudio обычно имеют расширение имени .RM. (Иногда для совместимости со старыми версиями проигрывателей используется расширение .RA, однако одного расширения здесь недостаточно. Для такой совместимости необходимо использовать также старые версии алгорит мов сжатия.) Однако если просто написать на своей веб-странице что- нибудь вроде

<A HREF="mymusic. гm">Слушайте музыку !</А>

то, скорее всего, звуковой файл mymusic.rm будет сначала загружаться, а лишь потом воспроизводиться. Чтобы обеспечить потоковое воспроизведение, нужно поступить следующим образом. Сначала создается файл, в котором нет ничего, кроме текстовой ссылки на музыкальный файл, например:

http://www.myprovider.com/~mypage/mymusic.rm

Обратите внимание на то, что следует указать полный URL-адрес файла, включая протокол доступа (скорее всего, это будет http://). Созданный файл может иметь любое имя с расширением .RAM (например mymusic.ram). Он изомещается на сервер, и гиперссылка дается именно на него:

<A HREF="mymusic. гаm">Слушайте музыку !</А>

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

<A HREF="mymusic. гат">Слушайте музыку! <I>(32 кбит/с, моно) </I></А>

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

Слушайте музыку!<BR>

<А HREF="mymusic.ram"> <I>(96 кбит/с, стерео) </I></A>

<BR>

<А HREF="inymusicl.ram"> <I>(64 кбит/с, моно) </I></A><BR>

<А HREF="myrnusic2.ram"> <I> (32 кбит/с, моно) </I></A><BR> <А HREF="mymusic3.ram"> <I>(16 кбит/с, моно) </I></A><BR>

<А HREF="mymusic4.ram"> <I>(8 кбит/с, моно) </I></A><BR>

<SMALL>Bы можете также послушать эту музыку с лучшим качеством (96 кбит/с, стерео), предварительно

<А HREF="mymusic.гт">загрузив ee.</A></SMALL>

Чтобы прослушивать файлы в формате RealAudio, необходима программа RealPlayer, которую можно бесплатно загрузить с сайта компании разработчика: www.real.com. А для функционирования потокового метода воспроизведения на сервере должна быть установлена программа RealServer. Обычно она бывает установлена на любом уважающем себя сервере, однако если с потоковым воспроизведением возникают какие-либо проблемы, то, скорее всего, нелишне проверить ее наличие, запросив об этом администратора сервера.

Формат МРЗ

Другой распространенный формат сжатия звуковых данных называется MPEG 1 Layer 3, а сокращенно — просто МРЗ (именно такое расширение имени обычно имеют файлы этого формата). Этот формат использует другие алгоритмы сжатия. Для некоторых звуковых файлов они подходят лучше, чем алгоритмы RealAudio, для некоторых — хуже). Кроме того, поддерживаются степени сжатия до 320 Кбит/с. Такое сжатие уменьшает исходный несжатый файл всего в четыре раза, зато его качество практи- чески неотличимо от “настоящего”. Часто используют МРЗ-сжатие с шириной потока 128 Кбит/с, при котором исходные файлы сжимаются приблизительно в 10 раз, а качество звучания все еще остается близким к оригиналу.

Формат MPEG 1 Layer 3 также поддерживает возможность потокового воспроизведения. Например, если в .RAM-файле указать файл формата МРЗ, то он тоже начнет воспроизводиться почти сразу же после нажатия на гиперссылку. Но все же главным преимуществом МРЗ является поддержка степеней сжатия от 128 до 320 Кбит/с, а такие скорости соединения с Интернетом встречаются не очень часто. При степени сжатия 64 Кбит/с и менее, как правило, более качественный результат дает сжатие в формате RealAudio. Поэтому МРЗ-файлы редко используют для прослушивания через Интернет. Обычно их предлагают сначала загрузить целиком. В отличие от WAVE-файлов, у МРЗ-файлов есть еще дно полезное свойство. Если при загрузке МРЗ-файла прервется связь и нет возможности дозагрузки, то это не так обидно, поскольку можно прослушать хотя бы ту часть файла, которая загрузилась.

Формат TwinVQ

Сравнительно новым форматом сжатия звуковых файлов является формат TwinVQ, созданный компанией Yamaha. Он отличается замечательными алгоритмами сжатия, позволяющими сжимать звуковую информацию с гораздо меньшей потерей качества. Например, файлы, сжатые TwinVQ до 96 Кбит/с по качеству звучания напоминают МРЗ-файлы, сжатые до 192 Кбит/с, причем часто звучат даже лучше последних. Таким образом, появилась возможность сжимать звуковую информацию почти в два раза плотнее, не теряя качество звука. Разумеется, возможно потоковое воспроизведение. Иногда файлы формата TwinVQ называют vqf-файлами (по их расширению). Правда, сжатие в формат TwinVQ занимает больше времени, чем сжатие в RealAudio или MPEG I Layer3, а воспроизведение отнияает больше ресурсов. Но это ощутимо только на устаревших компьютерах (Pentium 100 МГц и ниже).

Таким образом, для использования на веб-страницах подходят лишь немногие музыкальные форматы. Это, прежде всего, MIDI, а также три звуковых формата: TwinVQ, RealAudio и MPEG I Layer 3. Следует избе гать использования других форматов сжатия, имеющихся на сегодняшний день, по причине их низкого качества. Кроме того, не помещайте на свои веб-страницы несжатую звуковую информацию и файлы форматов типа WAVE, кроме специальных случаев, когда это действительно необходимо.


5.2

5.2. Программы для сжатия звуковых фрагментов

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

Чтение дорожек компакт-диска

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

Основное окно программы XingAudioCatalyst . При вставке звукового компакт-диска в дисковод CD-ROM в этом окне появляется список доро- жек, правда с названиями, принятыми по умолчанию: Track 1, Track 2 и т. д. Если список не появляется, нажмите кнопку Refresh (Обновить).

Чтобы увидеть названия дорожек, надо предварительно соединиться с Интернетом, а потом нажать кнопку CDDB. Через некоторое время загру- зится название альбома и имя исполнителя, а названия дорожек станут содержательными. Это возможно в том случае, если информация о данном компакт-диске имеется в базе данных CDDB. Как правило, она там есть. Теперь осталось отметить те дорожки, которые надо переписать. После этого можно нажать на кнопку Grab! (Перехват), и выбранные дорожки будут скопированы на жесткий диск.

Перед тем как нажимать эту кнопку, хорошо бы определить папку, в которую дорожки будут скопированы. Для этого нажмите кнопку Settings (Наст ройки) — откроется одноименное диалоговое окно. Здесь в самой верхней строке указывается та папка, куда будет копироваться звукозапись. Папку можно изменить с помощью кнопки Browse (Обзор).

Кроме того, в этом окне можно выполнить еще некоторые настройки. В раз деле CD-ROM access method (Метод доступа к СD-ROM) можно настроить пара метры чтения звуковых дорожек. Здесь имеются две вкладки. Для дисководов с интерфейсом SCSI выбирают вкладку ASPI, а с интерфейсом

IDE — вкладку MSCDEX. Затем при необходимости можно поменять способ чтения в раскрывающемся списке Rip Method и скорость чтения в раскрывающемся списке DAE Speed.

А в нижней части этого окна имеется еще пять вкладок, некоторые из которых могут оказаться полезными. Например, на вкладке Silence (Тишина) можно включить автоматическое удаление тишины в начале и/или конце каждой дорожки; для нас это как раз актуально — зачем же передавать через Интернет тишину? А на вкладке Misc. (Прочее) можно включить режим остановки после каждой ошибки, сбросив флажок Continue even if ynchronization fails (Продолжать при нарушении синхронизации). Вообще-то чслать это не рекомендуется, так как возникающие ошибки синхрониза-ции при чтении чаще всего ни на что не влияют, если их не слишком много подряд. Можно также заставить программу начать воспроизведение про-читанного сразу по окончании копирования или даже выключить ком-пьютер после этого.

Кроме того, в основном окне программы есть еще две полезные кнопки — NORM. (Нормализация) и МРЗ (Сжатие в МРЗ). Первая позволяет выбрать режим оптимизации амплитуды звукового файла в реальном времени (“ на лету ”). А кнопка МРЗ позволяет даже включить режим сжатия в формат МРЗ в реальном времени. Однако учтите, что, хотя каждая операция в отдель ности (нормализация и сжатие) занимает не слишком много времени, при выборе обеих сразу компьютер может не успеть все сделать — появятся сообщения об ошибках. Но не беспокойтесь — эти операции можно выпол нять порознь, для чего в диалоговых окнах Normalizing (Нормализация) и МРЗ (Сжатие в МРЗ) есть команды Normalize a wave file right now (Нормализовать звуко запись) и Create an МРЗ now (Сжать звукозапись в формат МРЗ).

Как видите, программу AudioCatalyst можно использовать не только для копирования звукозаписей с компакт-диска на жесткий диск, но и для сжатия их в формат МРЗ. Однако имейте в виду, что встроенный в нее модуль сжатия XingEncoder кодирует звук в формат МРЗ хоть и.быстро, но не всегда качественно. Так что в большинстве случаев лучше использовать другие программы сжатия.

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

Запись звука от внешнего источника

Итак, если исходный звуковой материал расположен на компакт-диске, то с записью все просто. А что делать, если он расположен на аудиокассете, мини-диске, ЛАГ-кассете или ином внешнем носителе? В этом случае придется осуществить обычную аудиозапись через звуковую карту компьютера. Соедините линейный выход вашего внешнего устройства с линейным входом звуковой карты. Затем дважды щелкните на значке с изображением динамика на панели индикации Windows (рис. 5.1). Откроется окно системного микшера. В нем из меню Параметры выберите пункт Свойства и в открывшемся диалоговом окне выберите пункт Запись. Нажмите кнопку ОК. Появится окно, изображенное на рис. 5.2.

Рис. 5.1. Панель индикации Windows

В этом окне следует выбрать линейный вход (Line). He закрывайте пока это окно — оно нам потребуется для регулировки уровня записи.

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

Рис. 5.2. Окно системного микшера Windows

Развлечения > Звукозапись), входящей в стандартную поставку Windows. Однако лучше это делать специализированными средствами, например программой Sound Forge. Если открыть эту программу и нажать кнопку Record (Запись) или комбинацию клавиш CTRL+R, откроется окно записи нового файла (рис. 5.3). Если здесь установить флажок Monitor (Индика ция), то уровень входного сигнала будет виден на индикаторе. Включите самое громкое место в своей записи и, изменяя уровень входного сигнала с помощью ползункового регулятора в окне системного микшера (рис. 5.4), добейтесь того, чтобы на самых громких звуках уровень был приблизи тельно равен -1 дБ, то есть был близким к максимальному, но ни в коем

Рис. 5.3. Окно записи в программе Sound Forge

случае не превышал его. Превышение уровня записи индицируется в окне программы Sound Forge красной надписью Clip, как показано на рис. 5.4. Такого допускать нельзя, так как в этом случае в записи появятся неустранимые искажения.

Рис. 5.4. Индикация перегрузки

Когда уровень записи установлен, можно начинать запись. Для этого нажмите кнопку Record (Запись). Во время записи постоянно мигает красная надпись Recording. Когда нужный фрагмент записан, нажмите кнопку Stop (Остановить), а затем кнопку Close (Закрыть). Сохраните записанный файл на диске комбинацией клавиш CTRL+S.

Теперь несколько замечаний. Обычно запись с внешнего источника осуществляется с помощью линейного входа, как было описано выше. Однако на многих современных звуковых картах имеется цифровой интерфейс S/PDIF. Если он у вас есть и вы осуществляете запись с DAT-кассеты или минидиска, то посмотрите, возможно, ваш DAT- магнитофон или MD- проигрыватель тоже имеют такой интерфейс. В этом случае целесообразно записывать звук не через линейный вход, а именно через S/PDIF, так как в этом случае процесс записи внесет в звук гораздо меньше искажений.

У проигрывателей минидисков довольно редко можно встретить обычный коаксиальный разъем S/PDIF, однако, как правило, они оснащаются оптическим входом/выходом. У некоторых современных звуковых карт также имеется оптический вход, хотя это пока и редкость. Проверьте, и если есть такая возможность, записывайте звук через оптический интерфейс. Правда, для этого потребуется специальный кабель.

Сжатие звука

Итак, звук записан и теперь его надо сжать. Кстати говоря, если вы его записывали программой Sound Forge, то можно, прямо не выходя из нее, сжать звук в формат RealAudio. Для этого дайте команду File > Save As (Файл > Сохранить как) — откроется диалоговое окно сохранения файла. В раскрывающемся списке Files of Type (Тип Файла) выберите тип RealNetworks G2 или Real Media для совместимости со старыми версиями — в этом случае качество звучания будет чуть хуже. После щелчка на кнопке Save (Сохранить) откроется окно, в котором можно выбрать параметры сжатия в виде описания. Если же использовать кнопку Advanced (Дополнительно), то можно выбрать степень сжатия в явном виде.

Если в вашей системе установлен модуль кодирования МРЗ, то вы сможете сжать файл с помощью МРЗ-алгоритма тоже непосредственно из программы Sound Forge. Для этого выберите в раскрывающемся списке Files of Type (Тип Файла) пункт Wave, а в раскрывающемся списке Format (Формат) - пункт MPEG Layer-3. При этом можно задать степень сжатия с помощью раскрывающегося списка Attributes (Характеристики). Однако учтите, что при этом будет записан файл, сжатый алгоритмом МРЗ, но в формате WAVE.

Запись в формате МРЗ

Если желательно получить на выходе файл в формате МРЗ, лучше вос- пользоваться программой МРЗ Producer, которую предлагает компания Fraunhofer. Основное окно этой программы изображено на рис. 5.5. Как видите, здесь все просто и нет ничего лишнего. Нажав кнопку Select Input (Выбор источника), можно выбрать WAVE-файл, подлежащий сжатию. Имя выходного файла предлагается автоматически, но если оно не годится, его можно задать с помощью кнопки Set Output (Задать выходной файл). С помошью раскрывающегося списка можно выбрать степень сжатия и режим (стерео/моно). Интересная особенность этой программы — возможность предварительного прослушивания фрагмента в сжатом виде. Для этого служит кнопка Prelisten (Предварительное прослушивание). С ее помощью можно сравнить между собой различные режимы сжатия и выбрать подводящий. Кодирование начинают щелчком на кнопке Encode (Кодировать).

Рис. 5.5. Основное окно программы Fraunhofer МРЗ Producer Professional

Если в меню Options (Параметры) установлен флажок Write RIFF/WAV- Format Files, то на выходе будет записан файл в формате WAVE. Чтобы получить МРЗ-файл, убедитесь в том, что этот флажок сброшен. А вот флажок High Quality Encoding установите обязательно — тогда качество выходного МРЗ- файла будет гораздо выше при той же степени сжатия. Без этой настройки процесс сжатия происходит гораздо быстрее, но качество при этом хуже — примерно такое же, как в программе AudioCatalyst.

Cписок один или несколько файлов. Щелкнув правой кнопкой мыши на значке любого файла в списке, можно индивидуально изменить степень его сжатия или предварительно прослушать его фрагмент (Prelisten). Нажатие кнопки Encode (Кодировать) запускает процесс сжатия всех файлов. внесенных в список.

Программа МРЗ Producer — очень качественный инструмент для сжатие звука в формат МРЗ. Она имеет лишь два недостатка, о которых, тем не менее, следует знать заранее. Во-первых, при сжатии в режиме моно к выбранном параметре High Quality Encoding она может работать нестабильно и в некоторых случаях “зависать”. Во-вторых, она не поддерживает сте пень сжатия 320 Кбит/с, в отличие от AudioCatalyst. Хотя эта последняя особенность в нашем контексте вряд ли актуальна.

Запись формата TwinVQ

Для того чтобы сжать файл в формат TwinVQ, также существует несколько программ. Одной из лучших является YAMAHA Sound VQ Encoder (ее можно загрузить с веб-сайта www.vqf.com). Программа имеет, кстати, довольно оригинальный дизайн. Обращаться с ней крайне удобно. Hа верхней панели можно ввести имя исходного звукового файла или выбрать его, нажав кнопку Browse (Обзор). При этом формат выбранного файла отображается автоматически. Затем с помощью раскрывающегося списке Encode Mode (Режим сжатия) можно задать степень сжатия. Только имейте в виду, что в этой программе указано количество бит в секунду на канал. То есть, если выбрать режим 32 kbps/ch для стереозаписи при установлен ном режиме Стерео, то фактически степень сжатия выходного файла составит 64 Кбит/с (по 32 Кбит/с на каждый из двух каналов).

С помощью переключателя Quality (Качество) можно выбрать качество сжатия: высокое, среднее и низкое. Чем выше качество, тем больше времени требуется программе для сжатия. Однако разница во времени не столь велика, чтобы жертвовать качеством, поэтому практически всегда следует выбирать параметр High (Высокое качество). На нижней панели можно выбрать имя выходного файла (программа по умолчанию предлагает то же имя, как и имя исходного файла, только рас-ширение заменяется на .vqf). Тут же можно указать дополнительные атрибуты, записываемые в ид-файл: название композиции, автора и данные об авторских правах. Можно также ввести собственное примечание.

Если установлен режим Permission to Save (Разрешить сохранение), то пользователь, прослушивающий этот файл в потоковом режиме, сможет сохранить его на жестком диске. Здесь же можно указать имя сохраняемого файла. А если включить режим Low Priority (Низкий приоритет), можно перевести процесс сжатия в фоновый режим. Хотя при этом кодирование займет, разумеется, больше времени, зато можно параллельно заниматься другими делами на компьютере.

С помощью SoundVQ Encoder можно также кодировать сразу несколько файлов в пакетном режиме. Для этого необходимо просто выбрать файлы в Проводнике Windows и перетащить их значки на панель программы. Далее будут предложены уже знакомые нам варианты настройки.

Кроме того, программа поддерживает функцию сжатия в режиме реального времени (“на лету”). Нажав кнопку Live Encoding (Сжатие в реальном времени), можно сжимать звуковой поток, поступающий на вход звуковой карты. Правда, для такого “живого” сжатия необходима достаточно мощная система.

Чтобы обеспечить потоковое воспроизведение, можно создать так называемый VQL-файл. Это текстовый файл, подобный упоминавшемуся выше RАМ-файлу, однако он может быть многострочным. В каждой строке при этом нужно указать местоположение одного VQF-фаи.ла (в виде полного URL-адреса, включая имя протокола http://). Таким образом, можно создать ссылку на несколько VQF-файлов, следующих подряд, то есть использовать VQL-файл в качестве своеобразного списка воспроизведения. Кроме того, в FQL-файл можно вставлять в конец строки любые примечания, отделив их знаком #.

Существуют и другие программы для сжатия файлов в формат TwinVQ. Некоторые из них можно загрузить, посетив уже упоминавшийся сайт www.vqf.com. Рекомендуем опробовать их самостоятельно.


5.3

5.3. Маленькие хитрости

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

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

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

Устранение постоянной составляющей

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

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

Рис. 5.6. Обычный синусоидальный сигнал

и он же с постоянной составляющей удалить. Во многих программах звуковой обработки имеются соответствующие средства. Например, в программе Sound Forge можно выбрать из меню Process (Обработка) пункт DC offset (Постоянное смещение) и в открывшемся окне выбрать автоматическое удаление постоянной составляющей. Программа сама определит ее наличие и, в случае необходимости, удалит.

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

Кроме того, фонограмма может иметь слишком малую амплитуду. Как .правило, с меньшими потерями сжимаются фонограммы, максимальная амплитуда которых достигает приблизительно -1 дБ. Если фонограмма слишком тиха, увеличьте ее уровень, а если он достигает 0 дБ, то лучше ero немного уменьшить. Для этого лучше всего пользоваться функцией нормализации. Например, в программе Sound Forge выберите из меню Process (Обработка) пункт Normalize (Нормализация). Установите уровень на отметку -1 дБ. Программа сама определит максимальный уровень амплитуды в записи и пересчитает в соответствии с ним все остальные уровни. Только обратите внимание, что при нормализации следует производить увеличение уровня до -1 дБ пиковой амплитуды — в Sound Forge это переключатель Peak. Если включить переключатель RMS, то все операции будут производиться со средним значением амплитуды сигнала, что для данного случая не подходит.

Но это еще не все. Описанная выше операция помогает, если уровень сигнала в записи остается практически постоянным. Однако бывают случаи, когда при наличии нескольких пиков на уровне около 0 дБ уровень всей остальной записи не поднимается, например, выше -30 дБ. В этом случае для получения лучшего звучания при сжатии необходимо уменьшить динамический диапазон записи. Для этого в Sound Forge существует функция Dynamics (Динамический диапазон). В других программах она может называться как-нибудь вроде Compressor/Expander/Limiter. В программе Sound Forge из меню Effects (Эффекты) выберите пункт Dynamics (Динамический диапазон) и далее — Graphic (Графическое представление). В открывшемся окне в большинстве случаев можно просто выбрать один из предварительно заданных наборов настроек. Нажав на кнопку Preview (Предварительное прослушивание), можно проверить результат.

Обратите также внимание на ползунковые регуляторы Threshold (Порог) и Ratio (Степень). Первый определяет порог уровня сигнала, ниже которого начинает действовать компенсация — соответствующее усиление сигнала. Регулятор Ratio определяет степень этой компенсации.

Нейтрализация шумов

Следующим мешающим моментом при сжатии могут быть шумы, присутствующие в записи. Для удаления шумов в звуковых программах также есть специальные средства. Например, в программе Sound Forge в меню Tools (Сервис) имеется пункт Noise Reduction (Шумоподавление). Однако здесь не все так просто. Конечно, “шумливая” запись после сжатия слушается не лучшим образом. Однако если шумов в записи много и они широкополосные, то их следует фильтровать очень осторожно. Дело в том, что при сильном понижении уровня широкополосного шума в самой фонограмме появляются спектральные провалы, часто слышимые как “присвист”, не говоря уже об изменении тембра полезного сигнала (инструментов, голоса и т.,п.). Если такую испорченную шумоподавлением фонограмму сжать в формате RealAudio или MPEG 1 Layer 3, то эффект спектральных провалов усилится, “присвисты” или другие артефакты будут гораздо слышнее, чем в несжатом звуке. При сжатии в формате TwinVQ этот эффект не так заметен, но все же присутствует.

Поэтому при шумоподавлении не стоит снижать уровень шумов более, чем на 15 дБ. В отдельных случаях (очень плохие записи, смешанные практически с белым шумом) приходится вообще отказаться от шумоподавления. Можно, конечно, произвести предварительную реставрацию специальными профессиональными средствами, но они, как правило, недоступны обычному пользователю ПК.

Устранение выделяющейся спектральной полосы

И, наконец, еще один момент. Если в записи присутствует сильно выделяющаяся спектральная полоса (это можно заметить визуально на так

Рис. 5.7. Две спектрограммы: обычной, звукозаписи и звукозаписи с сильно- выделяющейся частотной полосой

называемой спектрограмме или сонограмме). На рис. 5.7 показаны две спектрограммы звука — для обычной записи и для записи с сильной спек тральной полосой. Если такая выделяющаяся полоса присутствует, то лучше ее перед сжатием “сравнять” с остальными. Обычно это удается сделать с помощью графического эквалайзера. В программе Sound Forge выберите из меню Process (Обработка) пункт EQ (Эквалайзер) и далее — Graphic (Графический). Открывшееся окно очень похоже по виду на обычный графический эквалайзер, с помощью которого останется только уменьшить уровень выделяющейся частотной полосы.

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


6

6. Динамические веб-страницы на основе JavaScript

6.1. Простейшие примеры

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

Какими же способами пишутся такие веб-страницы? Ясно, что с помощью обычных тегов особой динамики достичь нельзя. Существуют, конечно, теги <MARQUEE> (“бегущая строка”, поддерживается только в Internet (Explorer) и <BLINK> (мигающий текст, поддерживается только в Netscape). Существует определенное в стандарте CSS2 стилевое свойство text-decoration: blink; (мигающий текст) и псевдокласс A:hover (изменение вида якоря/гипер- ссылки при наведении на них указателя мыши). Но это, конечно, еще не динамика.

Запись информации в веб-документ

Для написания динамических веб-страниц используются фрагменты кода, написанные на языке JavaScript (или другом языке сценариев, о чем речь пойдет ниже), который имеет синтаксис, отличный от HTML. Для отде ления этих фрагментов от остальной части HTML-документа они распоагаются между тегами <SCRIPT> и </SCRIPT> . Например, так:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>SCRIPT!</TITLE>

</HEAD>

<BODY>

<SCRIPT>

document.write("Эта страница написана на JavaScript!");

</SCRIPT>

</BODY>

</HTML>

Результат работы этого кода показан на рис. 6.1. Как видите, пока ничего необычного. Эту же надпись можно было написать и просто так, не используя JavaScript — результат был бы тот же. Зато теперь мы знаем, что если написать метод document.write, то на страницу будет вставлено то, что далее стоит в скобках. Если это текстовая строка, то нужно ее заключить еще и в кавычки.

Рис. 6.1. Простейшее использование JavaScript

Ладно, давайте немного изменим текст кода (для экономии места мы приводим только текст сценария, предполагая, что все остальные теги остаются такими же, как в предыдущем примере):

<SCRIPT> window.status = "Эта страница написана на JavaScript!"; </SCRIPT>

Результат можно увидеть на рис. 6.2. Теперь окно броузера абсолютно пустое! Но это и правильно, ведь мы же не вводили никакого текста. Зато если вы посмотрите на строку состояния, то увидите там нашу надпись. В этой строке всегда появляется значение, присвоенное объекту window.status. Знак равенства в JavaScript означает “присвоить значение”.

Рис. 6.2. Изменение строки состояния

Хорошо, скажете вы, вот мы уже управляем строкой состояния, но где же обещанная динамика? Ну, если не терпится, то можно еще немного изменить код предыдущего примера:

<SCRIPT> window.status = "Эта страница написана на JavaScript!"; setTimeout("window.status = 'А вы как думали?'",2000); </SCRIPT>

Теперь в момент загрузки наша страница будет выглядеть так же, как и в предыдущем примере, однако через две секунды содержимое строки состояния изменится на фразу “А вы как думали?”. Дело в том, что функция setTimeoutO, которую мы здесь использовали, совершает действие, определенное внутри нее, с некоторой задержкой. Эта задержка исчисляется в миллисекундах (тысячных долях секунды). Соответственно, значение 2000 соответствует задержке в 2 секунды.

Само действие определяется в виде строки, то есть должно быть заключено в кавычки. Поэтому фразу “А вы как думали?” пришлось заключить в другой тип кавычек — так называемые одинарные, чтобы броузер не “запутался”. В JavaScript (как и в HTML) допускается использование и тех, и других кавычек, нужно только внимательно следить, чтобы все кавычки в нужном месте закрывались. Нельзя было написать так:

. setTimeout("window.status = "А вы как думали?"", 2000);

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

Еще одна деталь: в JavaScript необходимо соблюдать регистр символов, так как в этом языке различаются прописные и строчные буквы. Напри мер, если вместо setTimeoutO написать SetTimeoutO или settimeoutQ, то будет выдано сообщение об ошибке.

Интерпретация языка JavaScript

Прежде чем рассмотреть какой-нибудь осмысленный пример, необходимо отметить еще несколько моментов. Во-первых, броузеры могут интерпре- тировать фрагменты JavaScript по-разному, но об этом речь пойдет ниже. Во-вторых, надо предусмотреть вариант, когда броузер вообще “не пони- мает” сценариев (сценариями называют фрагменты, написанные на языке JavaScript и других подобных интерпретируемых языках). В этом случае он, скорее всего, пропустит текст, заключенный между тегами <SCRIPT> и </SCRIPT> . Но тогда пользователь этого броузера ничего не увидит на экране. Чтобы таких неприятностей не происходило, придумайте альтернативный HTML-текст, который бы отображался в броузерах, не поддерживающих сценарии. Его нужно заключить между тегами <NOSCRIPT> и </NOSCRIPT> . Если же придумать такой текст совершенно невозможно, напишите между этими тегами хотя бы то, что для просмотра этой страницы необходим броузер, поддерживающий JavaScript, и поставьте на него гиперссылку.

Но это еще не все. Представьте себе, что броузер пользователя уж очень старый и вообще не понимает тег <SCRIPT> . Что будет тогда? Как и поло жено, он этот тег проигнорирует, и тогда весь код сценария отобразится на экране, а это совсем некрасиво. Чтобы этого избежать, принято заключать код сценария в теги комментариев <!-- и -->. Однако некоторые интерпретаторы JavaScript, встроенные в броузеры, при этом пытаются обработать второй из этих тегов. Поэтому перед ним обычно ставят сим вол JavaScript-комментария //. Таким образом, получается приблизительно следующее:

<SCRIPT>

window.status = "Эта страница написана на Javascript!"; setTimeout("window.status " 'А вы как думали?'", 2000); //--> </SCRIPT>

Учет версии броузера

Теперь давайте рассмотрим простой пример. Предположим, что у нас уже имеются страницы, созданные специально для броузера Internet Explorer 4, Netscape 4 или Netscape 6. Мы хотим написать код, который бы определял тип броузера пользователя и, в зависимости от этого, загружала бы одну из наших страниц. Кроме того, он должен выдавать предупреждение, если обнаружит устаревший броузер (версии 3 и ниже).

Сначала давайте напишем такое предупреждение. Чтобы пользователь наверняка обратил на него внимание, можно использовать метод alert. Применяется он точно так же, как уже знакомый нам метод document.write, но при этом выводит текст не прямо на страницу, а в диалоговое окно. Пока пользователь не нажмет кнопку ОК, работа сценария не будет продолжена.

Как определить номер версии броузера? Для этого существует свойство navigator.appVersion. Однако его значением является не число (собственно номер версии), а целая строка. Например, если написать:

document.write(navigator.appVersion) ; то в броузере Internet Explorer 5 будет выдано такое сообщение:

4.0 (compatible; MSIE 5.0; Windows 98; DigExt)

Netscape и другие броузеры также выдают подобную длинную строку. Как же выделить из нее номер версии?

К счастью, первая цифра этой строки во всех броузерах указывает именно на номер версии (в Internet Explorer 5 на этом месте оставили цифру 4, чтобы подчеркнуть сходство этих версий.) Поскольку после этого номера стоит точка, то есть не цифра, его легко выделить из всей строки с помощью функции parselnt(). Она всегда выделяет целое число из строки, останавливаясь на первой не цифре.

В данном случае нам надо, если номер версии меньше 4, выдать предупреждающее диалоговое окно. Для проверки условия в JavaScript существует оператор if, после которого в скобках следует поставить условие. Поэтому мы можем написать так:

if (parseint(navigator.appVersion)<4)

alert("Вы используете старую версию броузера.\nВ ней страница может отображаться неправильно") ;

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

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

Хорошо, предупреждение мы написали, теперь нужно определить тип броузера. Для этого существует свойство navigator.appName. В Internet Explorer его значением является “Microsoft Internet Explorer”, а в броузерах компании Netscape — просто “Netscape”. Поскольку для каждого случая нам надо предусмотреть ряд действий, удобно использовать оператор switch (пере ключатель). Схематично его использование можно изобразить так:

switch (условие) { case "первый случай":

какие-то действия case "второй случай": какие-то действия

и т. д. default: действия во всех остальных случаях

В нашем примере условием является значение navigator.appName, а случаи могут быть такими: "Microsoft Internet Explorer" и "Netscape".

switch (navigator.appName) { case "Microsoft Internet Explorer": какие-то действия

case "Netscape": какие-то действия

действия во всех остальных случаях

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

Чтобы загрузить другую веб-страницу вместо данной, нужно присвоить новое значение свойству window.location.href. Например, если написать:

window.location.href = "msie4.html";

то текущая страница будет заменена в окне броузера на страницу msie4.html. Давайте перед загрузкой новой страницы создадим соответствующее сообщение:

document-write ("Сейчас будет загружена страница для Internet Explorer 4") ;

setTimeout("window.local ion.href = 'msie4.html'", 3000);

При этом нам пришлось использовать функцию setTimeout, чтобы пользователь успел увидеть нашу надпись.

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

Если тип броузера определился как Netscape, нам нужно опять смотреть его версию. Мы можем использовать для этого оператор if...else:

if (parseint(navigator.appversion)<=4)

{ document.write ("Сейчас будет загружена страница для Netscape 4");

setTimeout("window, location.href = 'nn4.html'", 3000); } else

{ document.write ("Сейчас будет загружена страница для Netscape 6") ;

setTimeout("window.location.href = 'nn6.html'", 3000); } Если условие parselnt(navigator.appversion)<=4 верно, то выполняется блок операторов, следующий сразу после условия, а если неверно, то выполняется блок, следующий после ключевого слова else.

Кроме того, нужно предусмотреть действия для всех остальных случаев. Правда, таких случаев будет немного, поскольку многие броузеры (например Opera) любят представляться как Netscape. Однако предусмотреть такие действия все равно надо. Можно, например, предложить пользователю вручную выбрать нужную страницу:

alert ("Вы используете неизвестный нам тип броузера. \пСейчас вам будет предложено выбрать версию страницы, которую следует загрузить");

document.write ("<A HREF='msie4.html'>Страница для Internet Explorer 4</A><BR>");

document.write ("<A HREF='nn4.html'>Страница для Netscape 4 </A><BR>") ;

document.write ("<A HREF='nn6.html'>Страница для Netscape 6 </A>");

Итак, теперь посмотрим, что же у нас получается в целом:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD> <ТIТLЕ>Автоматический выбор нужной версии cтpaницы</TITLE>

</HEAD>

<BODY> <SCRIPT> < ! -- if (parseint(navigator.appVersion)<4)

alert("Вы используете старую версию броузера.\nВ ней страница может отображаться неправильно") ;

switch (navigator.appName)

case "Microsoft Internet Explorer":

document.write ("Сейчас будет загружена страница для Internet Explorer 4");

setTimeout ("window.location.href = 'msie4.html'", 3000); break; case "Netscape": if (parseint(navigator.appversion)<=4)

{ document.write ("Сейчас будет загружена страница для Netscape 4") ;

setTimeout("window.location.href = 'nn4.html'", 3000);

} else

{ document.write ("Сейчас будет загружена страница для Netscape 6");

setTimeout("window.location.href = 'nn6.html'", 3000);

} break;

default:

alert ("Вы используете неизвестный нам тип броузера.><nСейчас вам будет предложено выбрать версию страницы, которую следует загрузить");

document.write ("<A HREF='msie4.html'>Страница для Internet Explorer 4</A><BR>") ;

document.write ("<A HREF='nn4.html'>Страница для Netscape 4</A><BR>") ;

document.write ("<A HREF='nn6.html>Страница для Netscape 6</A>");

} //—> </SCRIPT>

</BODY>

</HTML>

Результат просмотра этой страницы зависит от броузера. На рис. 6.3 изображено предупреждение, которое получит пользователь при просмотре этой страницы в броузере Internet Explorer.

Рис. 6.3. Использование условной переадресации и временной задержки

Таблица умножения

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

Допустим, нам потребовалось представить таблицу умножения. Конечно, можно вручную написать каждую ее строку:

<TABLE>

<TR>

<TD>2&times;2=4</TD>

<TD>3&times;2=6</TD>

<TD>4&times;2=8</TD>

И Т.Д.

(Кстати, специальный символ &times; означает знак умножения.) Это способ достаточно долгий и нудный, кроме того, легко можно допустить случайную ошибку и не заметить ее. Давайте попробуем сгенерировать таблицу прямо “на ходу”, используя средства JavaScript. Teг <TABLE> можно вынести за пределы сценария. Далее, нужно сформировать некоторое количество строк (традиционно равное количеству вариантов второго множителя, который обычно принимает значения от 2 до 10). Можно этот множитель занести в переменную (назовем ее “I”) и написать:

for (i=2; i<=10; i++)

{ document.write ("<TR>"); document.write ("</TR>") ;

}

Выражение в скобках после оператора цикла for означает следующее: • начальное значение переменной — 2;

условие выполнения цикла — переменная должна быть меньше или равна 10;

на каждом шаге переменная увеличивается на 1 (обозначение “++” означает увеличение на единицу, а “- -” уменьшение на единицу.)

Если сейчас запустить этот цикл, то в окне броузера ничего не отобразится, поскольку пока нет тегов ячеек таблицы ( <TD> ). Поскольку в каждой строке должно быть столько ячеек, сколько значений принимает первый множитель (занесем его в переменную “j”), организуем между записью тегов <TR> и </TR> еще один цикл:

for (j=2; j<10; j++) document.write("<TD>"+j+"&times;"+i+"="+(i*j)+"</TD>") ;

Здесь условием выхода из цикла является j<10, а не j<=10, поскольку традиционно первый множитель в таблице умножения не превышает 9.

Обратите внимание на строку метода document.write. Здесь в кавычках указано то, что нужно непосредственно поместить на страницу. Переменные же указаны вне кавычек, чтобы в документ записывались их значения. Вся строка соединяется знаками “+”.

Чтобы получить результат умножения переменной i на переменную j, использована запись “i*j”. Знак * означает в JavaScript умножение, а знак / (косая черта) — деление. Есть еще операция “остаток от деления”, обозначаемая знаком %. Значение произведения i*j в нашем примере заключено в скобки, чтобы исключить возможность неправильной интерпретации броузером, хотя это не обязательно.

В принципе, наша таблица уже готова! Осталось только объявить переменные i и j в начале сценария (вообще-то, как правило, этого можно даже и не делать, но во избежание случайных ошибок лучше перестраховаться, да и вообще объявление переменных является хорошим тоном и облегчает восприятие кода). Для этого надо использовать ключевое слово var:

var i,j;

Кроме того, для улучшения восприятия, можно “разлиновать” таблицу, отделив столбцы друг от друга. Для этого, как вы помните, нужно исполь зовать атрибут RULES= тега <TABLE>:

<TABLE BORDER="1" CELLSPACING="0" CELLPADDING="2" RULES="cols">

Последним штрихом к форматированию нашей таблицы будет выравнивание текста в ячейках по правому краю. Для этого можно просто добавить после тега <TABLE> тег

<COLGROUP SPAN=10 ALIGN-"right">

или же просто определить в стилевом блоке свойство для тега <TD>:

TD { text-align: right; )

В нашем случае этот вариант, пожалуй, предпочтительнее, поскольку некоторые броузеры могут не распознать атрибут ALIGN= тега <COLGROUP>.

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Ta6лица умножения</TITLE>

</HEAD>

Teг <COLGROUP> задает группировку столбцов таблицы, а тег <COL> — вид каждого столбца, принятый по умолчанию. К сожалению, не все броузеры интерпретируют эти теги достаточно корректно.

<STYLE> BODY { text-align: center; background-color: #FCF7EC;

} TD { text-align: right; } </STYLE>

<BODY>

<Н2>ТАБЛИЦА УМНОЖЕНИЯ</Н2>

<TABLE BORDER""!" CELLSPACING="0" CELLPADDING="2" RULES="cols">

<SCRIPT> <!-- var i, j ; for (i=2; i<=10; i++) { document.write ("<TR>"); for (j=2; j<10; j++) document.write("<TD>"+j+"&times;"+i+"="+(i*j)+"</TD>") ; document.write ("</TR>") ; }

//-->

</SCRIPT>

</TABLE>

</BODY>

</HTML>

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

<COLGROUP SPAN=10 ALIGN="char" CHAR="=">

По идее, такая запись должна дать как раз требуемый результат — выровнять все знаки равенства в каждом столбце. Однако на момент написания этих строк такая возможность еще не реализована ни в одном броузере!

Запрос сведений у читателя

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

Рис. 6.4. Генерация таблицы “на лету”

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

mini = prompt ("Введите минимальное значение первого множителя", "2");

Здесь есть пояснение и поле для ввода, где уже приготовлено значение, принятое по умолчанию. И пояснение, и значение, принятое по умолчанию, необходимо указать при вызове метода prompt, как показано выше. Значение, введенное пользователем, будет присвоено переменной mini. Если пользователь нажмет кнопку Отмена, то этим значением будет null (так в JavaScript обозначается ничто, то есть отсутствие какого-либо значения).

Итак, с помощью метода prompt мы просим ввести значения (придется использовать этот метод 4 раза), присваиваем их переменным и подставляем эти переменные в условия цикла, например, так:

for (j=minl; j<=maxl; j++) document.write("<TD>"+j+"&times;"+i+"="+(i*j)+"</TD>");

<STYLE> BODY { text-align: center; background-color: #FCF7EC; }

TD { text-align: right; } </STYLE>

<BODY>

<Н2>ТАБЛИЦА ВОЗВЕДЕНИЯ В СТЕПЕНЬ</Н2>

<TABLE BORDER="1" CELLSPACING="0" CELLPADDING="2" RULES="cols">

<SCRIPT> <! -- var i,j; for (i=2; i<=10; i++) { document.write("<TR>") ; for (j=2; j<10; j++)

document.write("<TD>"+j+"<SOP>"+i+"</SUP>="+ Math.pow(j,i)+"</TD>") ;

document.write("</TR>") ;

} //-->

</SCRIPT>

</TABLE>

</BODY>

</HTML>

Если посмотреть внимательно, то можно заметить, что все отличие состоит в заголовках и строке записи ячейки. В ней мы использовали тег <SUP> для записи показателя степени. А для вычисления результата здесь исполь- зуется метод Math.pow, который, кстати, очень прост в использовании. Например, чтобы вычислить 5 7 , достаточно написать Math.pow(5,7).

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


6.2

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

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

записать их один раз в самом начале, поставив впереди ключевое слово function, то есть, определив их как функцию.

Описание функции

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

function fct(a)

{ if (<а==0)||(a==l)) return 1;

else { var i=1;

for (a; a>1; a--) i*=a; return i; } }

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

function fct(a)

Это означает, что функция будет называться fct() (можно использовать любое незарезервированное сочетание символов), а ее аргумент мы пока условно обозначили “а”.

Далее идет, собственно, “тело” функции, которое должно быть заключено а в фигурные скобки. В первой ее строке

if ((а==0)||(а==1)) return 1;

мы проверяем, не равен ли аргумент 0 или 1, и если это так, то функция возвращает результат — 1. Для возвращения результата применяется one- ратор return,

Если же аргумент не равен 0 или 1, выполняется следующий блок (идущий после ключевого слова else). Здесь мы определяем временную переменную i, в которую будем сохранять промежуточные результаты. Затем организуем цикл, причем в качестве счетчика используем сам аргумент, чтобы не вводить еще одну переменную. Запись i*=a — это просто сокращенная форма записи i=i*a, то есть мы перемножаем значения i и а, присваивая результат переменной i. Кстати, такая сокращенная форма записи существует для всех арифметических и логических операций, то есть можно записать х+=2 вместо х=х+2; z%=y вместо z=z%y и т. д.

Теперь, когда функция написана, ее можно вызвать из любого места. Например, если мы напишем где-нибудь выражение x=fct(5), то переменной х будет присвоено значение факториала от числа 5, то есть 120.

Чтобы не возникло ошибки вызова еще не определенной функции, рекомендуется определять их в разделе <HEAD> своего .HTML-файла. Теперь давайте попробуем проиллюстрировать сказанное.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТITLЕ>Вычисление факториала</ТITLЕ>

<SCRIPT> function fct(a) {

if ((a==0)||(a==l)) return 1;

else

{

var i=l; for (a; a>1; a--) i*=a; return i;

} } </SCRIPT>

</HEAD>

<BODY>

<SCRIPT>

var q; q=prompt ("Введите целое число от 0 до 170", "5");

q=parselnt(q) ;

if (isNaN(q)) alert ("Должно быть введено ЧИСЛО в пределах от 0 до 170");

else if (<q<0)||(q>170)) alert ("Число должно быть в пределах от 0 до 170") ;

else document.write(q+"l = "+fct(q)+"<BR>");

</SCRIPT>

</BODY>

</HTML>

При загрузке этой веб-страницы пользователю будет предложено ввести число в пределах от 0 до 170 поскольку для отрицательных чисел факториал не определен, а для чисел, больших 170, обычным способом вычис лить его не удастся — возникнет переполнение, и интерпретатор JavaScript выдаст в качестве результата ключевое слово Infinity, то есть бесконечность). Затем с помощью функции parselnt() мы выделяем из введенной строки целое число (если это не удается — выдается предупреждающее сообщение). Затем мы проверяем, входит ли это число в “разрешенный” диапазон (от 0 до 170). И, наконец, если все правильно, записываем результат, “попутно” вызывая нашу функцию fct().

Усложненный пример

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

function callitO {
var q; q=prompt ("Введите целое число от
0 до 170", "5") ;

q=parselnt(q) ; if (isNaN(q)) alert ("Должно быть введено ЧИСЛО в пределах от 0 до 170");

else if ((q<0)|| (q>l70)) alert ("Чиг-ло должно быть в пределах от 0 до 170");

else document .write<q+"! = "+fct(q)+"<BR>");

}

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

Теперь мы можем вызывать ее из “тела” документа сколько угодно раз, написав просто callit(). Например, можно организовать цикл для 10-кратного ее вызова:

for (var j=1; j<11; j++) callit();

Можно также организовать бесконечный цикл:

while (true) callit();

Для этого мы использовали оператор условной организации цикла while. Он проверяет условие, которое записано в скобках, и, если оно верно, выполняется действие (или блок действий), указанное после этого оператора.

Так повторяется до тех пор, пока условие не станет неверным. Здесь мы в качестве условия поставили ключевое слово true, которое всегда будет воз вращать значение “истина”. Поэтому цикл получится бесконечным.

Однако хорошо бы сначала спросить мнение пользователя, желает ли он повторения цикла, а то мы так и не позволим ему уйти со своей страницы. Для этого можно воспользоваться методом confirm. Он очень похож на метод alert, однако здесь пользователь имеет возможность нажать одну из двух кнопок (ОК или Отмена). Если нажата кнопка ОК, возвращается значение “истина” (true), если нажата кнопка Отмена, возвращается значение “ложь” (false).

while (confirm ("Повторить?")) callit();

Это уже лучше, но теперь при загрузке страницы пользователь сразу увидит запрос, повторить ли ему что-то, чего он еще не делал. Перед тем как задавать подобные вопросы, неплохо бы хоть один раз наше вычисление произвести. Чтобы цикл выполнялся до проверки условия, можно организовать его по-другому, используя ключевое слово do:

do callit(); while (confirm ("Повторить?"));

Теперь после вычисления каждого факториала пользователь будет иметь возможность выбора: повторить расчет или завершить. При нажатии кнопки Отмена выполняется выход из цикла. После этого можно продолжить загрузку документа (для иллюстрации мы просто подводим горизонталь ную черту под результатами вычислений).

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Вычисление факториала</ТITLЕ>

<SCRIPT> function fct(a) { if ((a=0)| | (a=l)) return 1;

else { var i=l ; for (a; a>l; a--) i*=a; return i; } }

function callit() { var q; q=prompt ("Введите целое число от 0 до 170", "5") ; q=parselnt(q) ; if (isNaN(q)) alert("Должно быть введено ЧИСЛО в пределах от 0 до 170");

else if ( (q<0) | | (q>170) ) alert("Число должно быть в пределах от 0 до 170");

else document.write(q+"! = "+fct(q)+"<BR>");

} </SCRIPT>

</HEAD>

<BODY>

<SCRIPT> do callit() ;

while (confirm ("Повторить?")) ;

document.write("<HR WIDTH=100 ALIGN”'left'>");

</SCRIPT>

</BODY>

</HTML>

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

Рис. 6.5. Расчет факториалов и запрос к пользователю

Конечно, появление лишних диалоговых окон в некоторых случаях может отпугнуть пользователя, особенно если у него на полную громкость вклю чены звуковые колонки (вывод окон alert и confirm обычно сопровождается стандартными звуками Windows). Поэтому лучше бы воздерживаться от их применения. Вместо этого можно использовать динамическое измене ния содержимого страницы.

Указание языка сценариев

Прежде чем пойти далее, давайте рассмотрим еще вот какой вопрос. Дело в том, что тег <SCRIPT> , так же как и другие теги, может иметь свои атри буты. Это LANGUAGE= (язык) и TYPE= (тип). В первом указывается язык, на котором написан сценарий. По умолчанию, значением этого атрибута явля ется JavaScript, так что если вы пишете обычный JavaScript-сценарий, то можете спокойно не указывать этот атрибут. Однако, если вы используете особенности версий 1.1 или 1.2 этого языка, то это необходимо указать:

<SCRIPT LANGUAGE”"JavaScript1.1">

ИЛИ

<SCRIPT LANGUAGE""JavaScript1.2">

Правда, распознать это смогут только броузеры Netscape последних версий. А если вы пишете страницу для отображения в броузере Internet Explorer, то можете использовать вообще другой язык — VBScript. Для этого необходимо указать соответствующее значение атрибута LANGUAGE=:

<SCRIPT LANGUAGE="VBS">

ИЛИ

<SCRIPT LANGUAGE="VBScript">

что, вообще говоря, одно и то же. В отдельных случаях могут применяться другие языки, для чего определены такие значения атрибута LANGUAGE=, как LiveScript, tal, PHP и другие.

Что касается атрибута TYPE=, то в нем можно на всякий случай указать тип сценария. В большинстве случаев это text/javascript (или text/vbscript для сценариев, написанных на VBScript).


6.3

6.3. Динамическое изменение внешнего вида страницы

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

Доступ к элементам HTML по номеру

Возьмем такой пример. Предположим, что мы поместили на веб-страницу графический элемент (картинку), но хотим, чтобы она не сразу возникла в своем реальном размере, а постепенно выросло “из ничего”. Для примера можно взять изображение компьютера ATARI-800, которое уже исполь- зовалось нами в главе 3. Карту графических ссылок мы в этом примере на него ставить не будем, хотя это легко сделать, просто перенеся код из последнего примера раздела 3.1'. Сначала просто поставим картинку на сграницу:

<IMG
SRC="Images/computer.gif" WIDTH="151"
HEIGHT="10" BORDER="0"
АLТ="Компьютер">

Физический размер этой картинки — 451х310, но мы, как видите, специально уменьшили ее ширину и высоту на 300 пикселов. Теперь давайте попытаемся обратиться к ней из сценария JavaScript.

Оказывается, доступ ко всем картинкам на странице можно получить, просто написав метод document.images и указав в квадратных скобках номер картинки на странице. Вообще говоря, такой синтаксис в JavaScript употребляется по отношению к массивам элементов. То есть, если у нас есть массив из пяти элементов под названием MoyMassiv, то к его элементам следует обращаться так: MoyMassiv[0], MoyMassiv[1],..., MoyMassiv[4]-. Мас сив document.images называется коллекцией.

Нумерация картинок начинается с нуля. Наша картинка, как первая на странице, будет иметь номер 0. Следовательно, для обращения к ней из сценария следует использовать метод document.images[0]. Если бы мы поместили на страницу еще одну картинку, после первой, то к этой второй кар тинке мы могли бы обратиться так: document.images[1].

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

if (document.images[0].width<451)

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

document.images[0].width+=2;

В данном случае мы увеличили ширину картинки на 2 пиксела. Точно так же можно поступить и с ее высотой:

document.images[0].height+=2 ;

Теперь, чтобы “зациклить” нашу функцию, можно просто в конце выз вать ее же после некоторой задержки. Например, если наша функция будет называться sizer(), то последней ее строкой может быть:

setTimeout("sizer()", 20);

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

while (document.images[0].width<451) setTimeout("sizer()", 20);

Однако для иллюстрации возможностей давайте все же применим рекурсивный вызов. Итак, посмотрим, что у нас получается.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Картинка с изменяющимся размером</ТIТLЕ>

<SCRIPT LANGUAGE""JavaScript">

function sizer () { if (document.images[0].width<451)

{
document.images[0].width+=2; document.images[0].height+=2;
setTimeout("sizer()", 20); } } //--> </SCRIPT>

</HEAD>

<BODY>

<IMG
SRC="Images/computer.gif" WIDTH="151"
HEIGHT”"10" BORDER="0"
АLТ="Компьютер">

<SCRIPT LANGUAGE="JavaScript">

sizer(); //-->

</SCRIPT>

</BODY>

</HTML>

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

document.images[0] width+=10;

document.images[0].height+=10;

setTimeout("sizer()", 100);

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

Кстати, нашу функцию sizer() легко переделать так, чтобы картинка, достигнув нормальных размеров, снова начала уменьшаться, затем опять увеличилась и так далее. Для этого надо прибавлять к размерам не просто число, а переменную:

document.images[0].width+=a; document.images[0],height+=a;

Тогда мы сможем присваивать этой переменной то положительное, то отрицательное значение, например, +2 и -2. Пусть изначально значение будет положительным:

var а=2 ;

причем это определение переменной не должно происходить внутри “тела” функции. Теперь, если картинка достигла нормальных размеров, изменим значение а на -2:

if (document.images[0].width>=451) a=-2;

Картинка начнет уменьшаться. Осталось при слишком маленьком ее раз-мере снова изменить значение а:

if (document.images[0].width<=151) a=2;

Посмотрим, как теперь будет выглядеть функция целиком (все остальное на этой странице остается таким же, как в предыдущем примере, поэтому мы не будем повторять текст всей страницы):

<SCRIPT LANGUAGE="JavaScript">

<!-- var a=2; function sizer()

( if (document.images[0].width>=451) a=-2;

if (document.images[0],width<=151) a=2;

document.images[0].width+=a;

document.images[0].height+=a;

setTimeout("sizer0", 20); }

//-->

</SCRIPT>

Итак, мы рассмотрели, каким образом можно получить доступ из сценария к любой картинке на веб-странице. Таким же способом можно управлять еще некоторыми элементами: ссылками и элементами тега <AREA> через метод document.links, формами через метод document.forms и document.forms[номep_формы].elements, якорями через метод document.anchors и т.д.

Доступ к элементам HTML по имени

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТITLЕ>Мигающий зaгoлoвок</TITLE>

<STYLE> BODY { background-color: #F9FFF9;

color: #OD160E; } H2 {

text-align: center; } P { text-indent: 3em;

} </STYLE>

</HEAD>

<BODY>

<Н2>Производство <ВR>МИГАЛОК<ВR> и цветомузыкальных установок </Н2>

<Р>Наша фирма является уникальным явлением на всем земном шаре. Вы спросите, почему? Подождите немного, скоро вы это сами поймете, если вам удастся дочитать этот текст до конца. Если же вам не удастся это сделать, то когда-нибудь вы очень сильно пожалеете об этом, говоря себе: а вот было оно совсем рядом, а я упустил его... Это мы про что, как вы думаете?</Р>

<Р>Итак, решено: вы, во что бы то ни стало, дочитываете этот текст до конца. (ДАЛЕЕ ИДЕТ КАКОЙ-НИБУДЬ ДЛИННЫЙ И СКУЧНЫЙ ТЕКСТ...)</Р>

</BODY>

</HTML>

Результат работы этой заготовки показан на рис. 6.6. Итак, проблема в том, чтобы заставить мигать слово “МИГАЛОК”. Ну, разумеется, можно применить стилевое свойство text-decoration: blink; или просто тег <BLINK> , но ни то, ни другое не поддерживается броузером Internet Explorer. Как же быть?

Прежде всего, надо выделить слово МИГАЛОК в отдельный элемент. Поскольку оно находится на отдельной строке, можно использовать тег <DIV>:

<Н2>Производство <DIV>МИГАЛOK</DIV> и цветомузыкальных установок.</Н2>

Чтобы иметь возможность управлять этим элементом, нужно дать ему уникальное имя, установив атрибут ID=:

<Н2>Производство <DIV ID="mig">МИГАЛOK</DIV> и цветомузыкальных установок.</Н2>

Теперь, если у пользователя броузер Netscape, можно сразу установит! мигающий стиль:

<Н2>Производство <DIV ID="mig" STYLE="text-decoration: blink;>МИГАЛOK</DIV> и цветомузыкальных установок.</Н2>

Рис. 6.6. Предварительная заготовка для веб-страницы с мигающим заголовком

Изменение свойств элементов

Поскольку Internet Explorer при этом не отобразит мигание, мы можем напи сать функцию, которая будет делать этот элемент то видимым, то невиди мым. Для этого нам пригодится стилевое свойство visibility. Сначала установим его так, чтобы элемент был виден:

<Н2>Производство <DIV ID="mig" STYLE="text-decoration: blink; visibility: visible;">МИГАЛОК</DIV> и цветомузыкальных установок.</Н2>

После этого остается проверить тип броузера, и если это не Netscape, вызвать функцию искусственного мигания (которую мы еще не написали):

if (navigator.appName!""Netscape") blink it();

Обратите внимание на то, что символ != означает неравно. Итак, эта функция должна то прятать наш элемент, то наоборот, показывать. Чтобы сдедать элемент невидимым, нужно присвоить его свойству visibility значение hidden. Поскольку мы дали элементу уникальное имя (с помощью атрибута ID=), теперь у нас есть возможность получить доступ к нему через коллекцию document.all:

document.all.mig.style.visibility="hidden";

Как видите, написав метод document.all, можно после точки просто указать имя элемента и далее любой атрибут, в данном случае STYLE=. После style можно снова поставить точку и указать любое стилевое свойство.

Чтобы сделать наше слово опять видимым, нужно присвоить свойству visibility значение visible:

document.all.mig.style.visibility="visible";

Теперь осталось только написать условие. Можно было бы просто написать:

if (document.all.mig.style.visibility="hidden") document.all.mig.style.visibility="visible";

else document.all.mig.style.visibility="hidden";

Однако давайте для большей гибкости и наглядности используем переменную флаг. Пусть она будет равна 1, если элемент видимый, и 0, если нет. Тогда мы можем в условии проверять именно этот флаг. Вся функция приобретет такой вид:

<SCRIPT LANGUAGE="JavaScript">

<!-- var vis=0; function blink it() { if (vis=l)

{ document.all.mig.style.visibility="hidden";

vis=0; } else { document.all.mig.style.visibility="visible"; vis=1;

} setTimeout ("blink_it()", 400); }

//--> </SCRIPT>

Как видите, изначально мы присвоили переменной-флагу vis значение 0, чтобы в первый же момент надпись МИГАЛОК не исчезала (при первом запуске функции теперь элемент будет видим). В конце функции мы используем задержку в 400 миллисекунд и рекурсивный вызов той же функции.

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

<BODY>

<Н2>Производство <DIV ID="mig" STYLE="text-decoration: blink;

visibility: visible;

">МИГАЛОК</DIV> и цветомузыкальных установок.</Н2>

<Р>Наша фирма является уникальным явлением на всем земном шаре. Вы спросите, почему? Подождите немного,скоро вы это сами поймете, если вам удастся дочитать этот текст

до конца. Если же вам не удастся это сделать, то когда-нибудь вы очень сильно пожалеете об этом, говоря себе: а вот было оно совсем рядом, а я упустил его... Это мы про что, как вы думаете?</Р>

<Р>Итак, решено: вы, во что бы то ни стало, дочитываете этот текст до конца. (ДАЛЕЕ ИДЕТ КАКОЙ-НИБУДЬ ДЛИННЫЙ И СКУЧНЫЙ ТЕКСТ...)</Р>

<SCRIPT LANGUAGE="JavaScript">

if (navigator.appName! ""Netscape") blink it(); //--> </SCRIPT> </BODY> </HTML>

Выбор изменяемых свойств

Кстати, использование переменной-флага дает нам возможность легко переделать это мигание во что-нибудь другое. Например, вместо временного исчезновения надписи можно на это время включать выворотку, то есть взаимно поменять цвет текста и цвет фона. Как мы уже говорили, получив доступ к элементу (например, через метод document.all), мы можем легко изменить любое его свойство. Вот, например, как можно организовать мигание с вывороткой:

function blink
it() { if (vis"1) {
document.all.mig.style.backgroundColor="#OD160E
document.all.mig.style.color="#F9FFF9"; vis=0;

} else { document.all.mig.style.backgroundColor="#F9FFF9" ;

document.all.mig.style.color="#OD160E"; vis=l; } setTimeout ("blink_it()", 400); }

Результат (в момент включения выворотки) показан на рис. 6.7. Обратите внимание на то, что стилевые свойства, которые пишутся через дефис в нашем примере это background-color), при доступе из сценария необходимо писать без дефиса, но заменив букву, идущую после дефиса, на прописную. Так, background-color превращается в backgroundColor, font-size в fontSize, border-style в borderStyle и т. д. Кстати говоря, чтобы получить тот результат, который показан на рис. 6.10, нам пришлось добавить еще одно свойство нашему мигающему элементу:

<Н2>Производство <DIV ID="mig" STYLE="text-decoration: blink; width: 7em; visibility: visible;">МИГАЛОК</DIV> и цветомузыкальных установок.</Н2>

а именно: мы установили ширину элемента. Если этого не сделать, цвет фона будет меняться на этой строке по всей ширине экрана.

Рис. 6.7. Мигание заголовка может осуществляться разными способами, в том числе и вывороткой

Доступ к элементам страницы через метод document.all — вещь очень удобная. К сожалению, такая возможность на 100% поддерживается только в броузере Internet Explorer. Что касается броузеров Netscape, то доступ к любому элементу там появился только в шестой версии, но синтаксис его отличается от рассмотренного выше. Вместо documental).имя_элемента для Netscape 6 нужно писать document.getElementByld("имя_элементa"). А в более ранних версиях Netscape доступ обеспечивается только к некоторым элементам страницы: рисункам (document.images), ссылкам (document.links), якорям (document.anchors), элементам управления и внедренным объектам (document.applets), формам (document.forms), объектам, внедренным с помощью тега <EMBED> (document.embeds), а также слоям, которые в Netscape организовывались с помощью тега <LAYER> (через document, layers). При этом, правда, все равно можно присваивать этим элементам уникальные имена и затем использовать их для обращений, например, так:

<A NAME="colored">Какой-то текст<А> <SCRIPT> document.anchors.colored.style.color="red"; </SCRIPT>

При этом некоторые версии Netscape позволяют опустить слово style, а при доступе к слоям — и слово layers.

Эти отличия несколько затрудняют создание страниц, которые бы хорошо смотрелись и в Internet Explorer, и в Netscape. Однако всегда можно проверить из сценария тип и версию броузера, после чего написать различные блоки кода для разных броузеров. В некоторых особо сложных случаях можно даже написать отдельные страницы для разных типов броузеров, и организовать перенаправление на них (пример такого перенаправления был приведен в разделе 6.1). В любом случае не забывайте проверять, как веб-страница смотрится в броузерах других типов. Сложно, конечно, поддерживать совместимость со всеми броузерами, но даже если ориентироваться на какой-нибудь один из них, все равно иногда стоит немного подкорректировать код так, чтобы пользователи других броузеров увидели хоть что-то более или менее похожее. Кстати, в этой книге большинство примеров ориентированы на броузер Internet Explorer версии 4 и выше.


6.4

6.4. Другие возможности языка JavaScript

Дополнительные операторы JavaScript

Подведем промежуточный итог знакомства с JavaScript. На самом деле, мы с вами рассмотрели не так уж мало: достаточно сказать, что мы изучили практически все операторы этого языка. Конечно, все дело в том, что их не так много: операторы организации циклов (for, while и do...while), услов ные операторы (if и switch) и операторы манипулирования объектами, кото рые мы пока не рассматривали. Этих операторов всего два: with и for...in. Оба применяются в основном для сокращения объема вводимого текста. Например, вместо того чтобы написать

document.open (); document.write("Привет!") ; document.close();

можно использовать такую сокращенную запись:

with (document) {

open () ;

write("Привет!");

close ();

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

Другой оператор — for... in так же, как и оператор for, организует цикл. Но только вместо условия цикла при этом нужно указать объект, по всем свой ствам которого этот цикл и “пройдется”. Наверное, предыдущая фраза была не совсем понятна, поэтому поясним ее на примере.

Мы уже знаем о двух свойствах, позволяющих определить версию броузера —это navigator.appName и navigator.appVersion. Оба принадлежат объекту navigator. А между прочим, у этого объекта есть еще ряд интересных свойств. Чтобы их просмотреть, давайте создадим страницу, содержащую небольшой сценарий.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Cвойствa Navigator</TITLE>

</HEAD>

<BODY>

<SCRIPT>

for (q in. navigator) document.write(q+"="+navigator[q]+"<BR>") ;

</SCRIPT>

</BODY>

</HTML>

Работает этот сценарий следующим образом. Переменной q поочередно присваивается имя каждого свойства объекта navigator. На экран при этом выводится (с помощью метода document.write) имя свойства (q), и, после знака равенства, значение свойства — (navigator[q]) . Таким образом, можно узнать о свойствах, о существовании которых мы до этого даже не подо зревали!

Вот, например, что нам покажет броузер Internet Explorer версии 5.0, если загрузить в него эту страницу:

appCodeName=Mozilla
appMinorVersion=0 appName=Microsoft Internet Explorer
appVersion=4.0 (compatible; MSIE 5.0; Windows 98; DigExt)
cookieEnabled=true cpuClass=x86 mimeTypes=

onLine=true
opsProfile= platform=Win32 plugins= systemLanguage=ru
userAgent=Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)
userLanguage=ru userProfile=

Как видите, свойств довольно много. Некоторые из них, правда, дублируют друг друга. Например, свойство appMinorVersion — это число, стоящее после точки в appVersion (номер подверсии). А значение свойства userAgent состоит из комбинации значений appCodeName и appVersion. Кстати, различные броузеры покажут нам не только различные значения свойств, но и представят различный их набор. Вот, например, результат загрузки той же страницы в броузер Netscape 6:

appCodeName=Mozi1
la appName=Netscape appVersion=5.0 (Windows; en-US)
language=en-US mimeTypes=[object MimeTyi " •Array]
platform=Windows plugins=[object PluginArray] securityPolicy=

userAgent=Mozilla/5.0 (Windows; N; Win98; en-US; ml4) Netscape6/ 6. Obi

cookieEnabled=true

Таким образом, оператор цикла for...in можно использовать не только для сокращения времени “стучания по клавиатуре”, но и для исследования броузера!

Кстати, условный оператор if также имеет сокращенную форму записи, которую в некоторых случаях удобно применять (особенно если условие и выполняемые действия достаточно компактны). Для этого следует про сто написать условие, затем поставить знак вопроса, и после него указать действие, выполняемое в случае правильности условия. Затем, после двое точия, можно указать действие, выполняемое в противном случае.

Например, вместо:

if (a<=100)
some function(a) ; else alert("Число превышает
допустимое значение!");

можно написать так:

(а<=100) ? some function(a) : alert("Число превышает допустимое значение!");

Здесь some_function() — просто какая-то функция, определенная где-то на веб-странице.

Встроенные функции JavaScript

Теперь о функциях. Мы уже научились определять собственные функции. Кроме того, в JavaScript существуют так называемые встроенные (или предопределенные) функции. Некоторые из них мы уже знаем — это isNaNQ и parselnt(). Кстати, функция parselnt() имеет еще одну замечательную особенность: с ее помощью можно распознать число, введенное в любой системе счисления, начиная от двоичной и кончая 36-ричной. Для этого нужно просто в качестве второго аргумента указать основание системы счисления, например, вот так: parselnt("1110", 2);

В этом случае строка 1110 будет интерпретирована как двоичное число, и результатом функции будет число 14.

Кроме этих двух функций существуют еще функции parseRoat() и isFinite(). Функция parseFloat() не может принимать второй аргумент, зато может выделить из строки дробное число. Например, если написать

parseint("3.289 times"); то результатом выполнения функции будет число 3, а если написать

parseFloat("3.289 times");

результатом будет число 3,289. Кроме того, с помощью этой функции можно распознать число, введенное в нормализованной форме, например:

parseFloat ("3.755е-2") ; даст в результате 0,03755.

Что касается функции isFinite(), то она принимает значение истина, если аргумент является числом, или ложь — в противном случае. Как вы можете заметить, она делает то же, что и функция isNaN(), только с противоположным результатом.

Существует еще полезная функция eval(). Она обычно определяется, как вычисление выражения без ссылки на конкретный объект. Сходу это понять довольно трудно.

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

Math.pow(j,i)

Такие конструкции, как правило, являются методами одного из встроенных объектов. Если вы пока плохо представляете себе, что это такое, не огорчайтесь. Для их употребления это совершенно не важно, поскольку их синтаксис очень похож на синтаксис функций. Например, выше было продемонстрировано возведение в степень. Можно осуществлять и другие действия с помощью объекта Math. Например, для округления числа i до ближайшего целого достаточно написать Math.round(i), а для вычисления его синуса — Math.sin(i).

Кроме того, можно пользоваться свойствами объекта Math. Если, к примеру, потребовалось ввести число тг, то не стоит вспоминать его с точностью до какого-то там знака — достаточно написать вместо него Math PI. Можно точно так же определить другие важные математические константы.

Помимо объекта Math, в JavaScript имеются и другие, например Array для работы с массивами, Date для работы с датами и прочие.


7

7. Веб-страницы, реагирующие на действия пользователя

7.1. Ввод данных пользователем в формы HTML

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

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

Получение информации от пользователя

В качестве примера давайте рассмотрим страницу для отзывов клиентов об услугах гипотетической фирмы “Лентяй”. Это, конечно, будет не совсем то, что обычно подразумевается под книгой отзывов на сайте. Просто мы предоставим пользователю возможность ввести информацию и отправить ее на сервер (как уж она будет там обрабатываться, мы сейчас рассматривать не будем).

Итак, возьмем заголовок и правую часть веб-страницы. Только добавим ссылку на страницу “Услуги” и снимем ее с “Книги отзывов”:

<DIV CLASS="rght">

<DIV CLASS="lnk"><A HREF="main.html">УСЛУГИ

</A>

</DIV> <DIV CLASS="lnk">

<A HREF="prices .html">ЦЕНЫ

</A>

</DIV>

<DIV CLASS="lnk">

<A HREF="forml.html">Форма 3AKA3A

</A>

</DIV>

<DIV CLASS="lnk">

<A HREF="history.html">История

<SPAN STYLE="letter-spacing: -3px; ">KOMПAHИИ

</SPAN>

</A>

</DIV>

<DIV CLASS="lnk">Книга OT3ЫBOB</DIV>

А в левую часть страницы давайте поместим форму. Для этого сначала добавим специальный тег <FORM>, без которого невозможно будет отправить данные на сервер обычными средствами. Здесь нам потребуется указать атрибут METHOD=, с помощью которого броузер определяет способ отправки данных: в виде “добавки” к строке URL (метод get) или в виде блока данных (метод post). В качестве значения атрибут ACTION= необходимо указать URL-адрес сервера, куда отправятся данные. Здесь можно также указать адрес электронной почты (с префиксом mailto:) — в этом случае данные формы отправятся по указанному адресу. В нашем случае давайте укажем гипотетический URL-адрес сервера cgi.lentyay.com, где обработка данных формы будет происходить с помощью какого-нибудь CGJ-сценария:

<FORM ACTION="http://cgi.lentyay.corn/guest.cgi" METHOD="post">

В конце формы должен стоять закрывающий тег </FORM>. Все, что находится внутри, можно будет сообщить серверу. Для отправки данных формы традиционно используется кнопка с названием Submit (Отправить). Для ее создания можно использовать тег <INPUT> с атрибутом TYPE="submit":

<INPUT TYPE="submit" VALUE="Отправить">

Атрибут VALUE= при этом определяет надпись на кнопке. Если его не задать, то на кнопке будет написано Submit. Какие же данные будут отправлены? Для начала давайте спросим у пользователя его имя, выделив для этого небольшое однострочное текстовое поле, и мнение об услугах фирмы, для чего выделим многострочное текстовое поле.

Поля для ввода текста

Чтобы создать однострочное текстовое поле, нужно также воспользоваться тегом <INPUT> , но уже с атрибутом TYPE="text". При этом его ширина задается с помощью атрибута SIZE=. Чтобы программе обработки данных (или человеку, который будет в этих данных разбираться) было понятно, какие данные к какому полю относятся, желательно для каждого поля указать атрибут NAME=. В данном случае мы запрашиваем у пользователя его имя, поэтому пусть значением этого атрибута будет слово Имя (по-английски тоже Name):

<INPUT TYPE="text" NAME="Name" VALUE="Аноним" SIZE="30">

При этом атрибут VALUE= определяет, что будет изначально написано в текстовом поле. Обратите внимание на то, что атрибут SIZE= определяет только видимую ширину текстового поля, но вовсе не ограничивает количество вводимых пользователем символов. Если же надо ввести такое ограничение, то следует пользоваться атрибутом MAXLENGTH=.

— Хорошо, — скажете вы, — но как пользователь узнает, что от него требуется ввести в это поле?

Чтобы дать ему “подсказку”, можно просто написать ее текст перед текстовым полем:

Ваше имя: <INPUT TYPE="text" NAME="Name" УАШЕ="Аноним" SIZE="30">

Однако лучше воспользоваться тегом <LABEL> , который был введен в Internet Explorer версии 4. Он гарантирует привязку метки к полю ввода. В нем нужно указать единственный атрибут FOR=, значение которого должно содержать имя поля ввода:

<LABEL FOR="Name">Baшe имя:</LABEL>

<INPUT TYPE="text" NAME="Name" VALUE="AHOHИM" SIZE="30"><BR>

Теперь давайте создадим многострочное текстовое поле для ввода мнения клиента об услугах фирмы. Для этого необходимо использовать тег <TEXTAREA>. В нем можно с помощью атрибутов COLS= и ROWS= определить количество символов в строке и число строк текстового поля:

<TEXTAREA COLS="30" ROWS="4" NAME”"Opinion" STYLE="vertical-align: middle;"></TEXTAREA>

Как видите, здесь мы также определили атрибут NAME=. А поскольку это текстовое поле является многострочным, мы применили еще и стилевое свойство vertical-align, чтобы “подсказка” пользователю расположилась по центру (по умолчанию она располагается внизу).

Кроме того, не забудьте поставить закрывающий тег </TEXTAREA> , поскольку все, что находится между открывающим и закрывающим тегами, будет трактоваться как содержимое текстового поля. Если не поставить закрывающий тег, все последующее содержимое веб-страницы окажется в текстовом поле, причем в виде исходного текста!

Теперь давайте добавим еще одну “традиционную” кнопку, при нажатии на которую все поля формы очищаются (или приобретают исходные значения, определенные атрибутом VALUE= — в данном случае при ее нажатии в поле Ваше имя появится запись Аноним). Такую кнопку можно создать с помощью тега <INPUT> с атрибутом <TYPE="reset">:

<INPUT TYPE="reset" VALUE ="Очистить форму">

Как и в случае с кнопкой Submit, значение VALUE= здесь определяет надпись на кнопке. Если этот атрибут не установлен, на кнопке будет написано: Reset. Давайте посмотрим, что v нас получается в целом.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Baш отзыв</ТIТLЕ>

<STYLE> BODY { background-color: #D2FFFF;

color: #003737; background-image: url("Images\grad2.jpg");

background-position: right;

background-repeat: repeat-y;

} HI { text-align: center } A:link,A:active,A:visited {

color: #006A6A;

} A:hover { font-weight: bold; text-decoration: none;

} .hdr { position:

absolute;

left: 50px;

top:

10px;

text-align:

center;

font-family:

OdessaScriptFWF, fantasy; font-size: 60px;

font-weight: 900;

width: 90%;

height: 100px;

letter-spacing: 0.05em;

line-height: 100px;

filter: shadows- border:

10px outset #003163;

color: #3163CE; }

.1ft {

position: absolute;

font-size: meduim;

left: 10px;

top: 160px;

width: 160px;

height: 400px;

overflow-x: visible;

} .Ink {

border-width: thick;

border-style: ridge;

margin: 10рх;

padding: 5px;

border-color: #319CFF;

background-image: url("Images\backlnkl.jpg") ; color: red;

text-align: center; }

.Ink A {

text-decoration: none; color: white;

} .logo {

position: absolute;

left: 150; top: 220;

z-index: -5;

} </STYLE>

</HEAD>

<BODY>

<DIV CLASS="hdr">Фиpмa&nbsp;&laquo;ЛEHTЯЙ&raquo;</DIV>

<DIV CLASS="rght">

<DIV CLASS="lnk">

<A HREF="main.html">УСЛУГИ</A>

</DIV> <DIV CLASS="lnk">

<A HREF="prices .html">ЦЕНЫ</A></DIV>

<DIV CLASS="lnk">

<A HREF="forml .html">ФOPMA 3AKA3A</A> </DIV>

<DIV CLASS="lnk">

<A HREF="history.html">ИСТОРИЯ <SPAN STYLE="letter-spacing: -3рх; ">КОМПАНИИ</SРАN></А>

</DIV>

<DIV CLASS="lnk">KHHГA OT3ЫBOB</DIV>

</DIV> <DIV CLASS="lft">

<Н1>Ваш отзыв с наших услугах</Н1>

<DIV ALIGN="center">

<FORM ACTION="http://cgi.lentyay.corn/guest.cgi" METHOD="post">

<LABEL FOR="Name">Bame имя:</LABEL>

<INPUT TYPE="text" NAME="Name" VALUE="Аноним" SIZE="30">

<BR>

<LABEL FOR="Opinion">Baшe мнение:</LABEL>

<TEXTAREA COLS="30" ROWS="4" NAME="Opinion" STYLE="vertical-align: middle; "></TEXTAREA>

<BR> <INPUT TYPE="submit" VALUE="Отправить">

<INPUT TYPE="reset" VALUE="Очистить форму"> </FORM> </DIV> </DIV>

<IMG
CLASS="logo" SRC="Imqes/logo6.gif"
WIDTH="500" HEIGHT="346"
BORDER="0">

</BODY>

</HTML>

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

Списки

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

Выбор возрастной категории можно организовать в виде раскрывающегося списка. Для создания такого списка используется тег <SELECT> . Между ним и его закрывающим тегом </SELECT> можно поместить несколько пунктов будущего списка. Каждый из них должен начинаться с тега <OPTION> . В данном случае мы можем написать так:

<SELECT NAME="Age" SIZE="1">

<OPTION VALUE="10">менее 20

<OPTION VALUE="20">20&ndash;30

<OPTION VALUE="30">30&ndash;40

<OPTION VALUE="40">40&ndash;50

<OPTION VALUE="50">50&ndash;60

<OPTION VALUE="60">6onee 60 </SELECT>

Рис. 7.1. Простейшая форма HTML

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

Вы, вероятно, обратили внимание еще на один атрибут тега <SELECT> — атрибут SIZE=. Здесь его значение равно 1 (кстати, это значение определено по умолчанию, так что можно было этот атрибут и не указывать). Если указать значение, большее 1, то в окне броузера вместо раскрывающегося списка отобразится так называемый прокручиваемый список. На рис. 7.2 приведен пример прокручиваемого списка при атрибуте SIZE="3". Как видно, в данном случае в списке одновременно отображаются три строки (число одновременно отображаемых строк прокручиваемого списка и определяется с помощью атрибута S1ZE=). Если же надо дать пользователю возможность выбора сразу нескольких пунктов из списка, то в теге <SELECT> надо установить атрибут MULTIPLE=.

Рис. 7.2. Прокручиваемый список

Переключатели

помощью такого списка можно было бы организовать и выбор пола, однако давайте применим для этого другой элемент формы — переключатели. Они употребляются группами, в которых только один переключатель может быть включен одновременно. Каждый из переключателей создается с помощью тега <INPUT> с атрибутом TYPE="radio". В группу будут объединены те переключатели, теги которых имеют одинаковые значения атрибута NAME=. Например, в данном случае мы можем написать так:

<LABEL FOR="Sex">Baш пол:</LABEL>

<INPUT
TYPE="radio" NAME="Sex"
VALUE="М">Мужской <INPUT
TYPE="radio" NAME="Sex"
LABEL="F">Женский

Как видите, значение атрибута NAME= одинаково у обоих тегов <INPUT> , поэтому пользователь не сможет выбрать оба пункта одновременно (при выборе одного из пунктов выбор предыдущего отменяется). Кстати, в этом примере изначально не выбран ни один из пунктов. Если же надо, чтобы какой-либо пункт был выбран заранее, то необходимо в соответствующем теге <INPUT> установить атрибут CHECKED, например, вот так:

<INPUT TYPE="radio" NAME°"Sex" VALUE="F" СНЕСКЕD>Женский

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

Флажки

Теперь давайте спросим пользователя о его интересах. Для этого органи зуем список из нескольких пунктов, которые он сможет отметить флаж ками. Каждый из пунктов такого списка создается с помощью все того же тега <INPUT> , однако теперь у него должен быть атрибут TYPE="checkbox". Впрочем, этот вариант практически ничем не отличается от предыдущего, кроме того, что пользователь может выбрать сразу несколько пунктов или даже все. Например:

<LABEL FOR="Interestsl">Baiim интересы :<BR></LABEL>

<INPUT TYPE="checkbox" NAME="Interestsl" VALUE="Computers">КОМПЬЮТЕРЫ

<INPUT TYPE="checkbox" NAME="Interests2" VALUE="Sports">Cnopт

<INPUT TYPE="checkbox" NAME="Interests3" VALUE="Art">Иcкyccтво

<INPUT TYPE="checkbox" NAME="Interests4" VALUE="Science">Hayкa

В данном случае мы установили для каждого пункта разные значения атрибута NAME=, но они могли бы быть и одинаковыми. Как и в предыду щем случае, здесь можно установить атрибут CHECKED, чтобы соответствующий пункт появился на экране заранее отмеченным по умолчанию.

Давайте посмотрим, что у нас получается (для экономии места приведем текст не всей страницы, а только ее левой части):

<DIV CLASS="lft"> <Н1>Ваш отзыв о наших услугах</Н1>

<DIV
ALIGN="center"> <FORM
ACTION="http://cgi.lentyay.corn/guest.cgi"
METHOD="post"> <LABEL
FOR="Name">Baшe имя:</LABEL>

<INPUT
TYPE="text" NAME="Name"
VALUE="Аноним"
SIZE="30"><BR><BR> <LABEL
FOR="Age">Baш возраст:</LABEL>

<SELECT NAME="Age" SIZE="1">

<OPTION VALUE""10">менее 20 <OPTION VALUE="20">20&ndash;30 <OPTION VALUE="30">30&ndash;40

<OPTION VALUE="40">40&ndash;50

<OPTION VALUE="50">50&ndash;60

<OPTION VALUE="60">6onee 60 </SELECT>

<BR><BR>

<LABEL FOR="Sex">Baш noл:</LABEL>

<INPUT TYPE="radio" NAME="Sex" VALUE="М">Мужской

<INPUT TYPE="radio" NAME="Sex" VALUE="F">Женский

<BR><BR> <LABEL FOR="Interestsl">Baши интересы:<BR></LABEL>

<INPUT TYPE="checkbox" NAME="Interestsl" VALUE="Computers">Компьютеры

<INPUT TYPE="checkbox" NAME="Interests2" VALUE="Sports">Cnopт

<INPUT TYPE="checkbox" NAME="Interests3" VALUE="Art">Иcкyccтво

<INPUT TYPE="checkbox" NAME="Interests4" VALUE="Science">Hayкa

<BR><BR> <LABEL FOR="Opinion">Baшe мнение:</LABEL>

<TEXTAREA COLS="30" ROWS="4" NAME="Opinion" STYLE="vertical-align: middle; "></TEXTAREA>

<BR><BR> <INPUT TYPE="submit" VALUE="Отправить">

<INPUT TYPE="reset" VALUE="Очистить форму">

</FORM>

</DIV>

</DIV>

Результат работы кода показан на рис. 7.3. Как видите, эта форма полу чилась более разнообразной благодаря использованию разных типов эле ментов управления для ввода данных. Поэтому она и смотрится более привлекательно.

Рис. 7.3. Форма с элементами управления

Группы элементов формы

Неплохо бы было еще логически объединить то, что связано со сведениями о пользователе, и то, что связано с его мнением. Для такого группирова ния элементов форм в HTML 4.0 был введет тег <FIELDSET> . Все, что нахо дится между ним и его закрывающим тегом </FIELDSET> , будет обведено в рамку и озаглавлено так, как указано в теге <LEGEND>. Теги <FIELDSET> и <LEGEND> поддерживаются пока только в Internet Explorer версии 4 и выше, а броузер Netscape начал поддерживать их только в шестой версии. Кроме того, элементы <FIELDSET> пока не очень хорошо позиционируются на веб- страницах. Как вы увидите в следующем примере, для корректного цент рирования их на странице (в Internet Explorer 5) нам пришлось поместить всю форму в центрированную таблицу и, кроме того, отдельно центриро вать то, что расположено между каждой парой тегов <FIELDSET> и </FIELDSET>.

Тег <FIELDSET> можно употребить следующим образом:

<FIELDSET Т1ТЬЕ="Сведения о клиенте"> <LEGEND ALIGN="left">Paccкaжитe о ce6e</LEGEND>

После этого можно поместить несколько элементов формы и поставить закрывающий тег </FIELDSET> . В броузере Internet Explorer значение атрибута TITLE= выводится в качестве всплывающей подсказки при наведении мыши на содержимое элемента <FIELDSET> . Кстати, это относится также и к другим тегам, которые могут иметь атрибут TITLE=. Можно, например, установить его даже у элемента <BODY> . А то, что находится между тегами <LEGEND> и </LEGEND> , будет вынесено в заголовок рамки.

Аналогично, давайте создадим рамку для той части формы, в которую пользователь вводит свое мнение:

<FIELDSET TITLE="Baшe мнение">

<LEGEND ALIGN=left>Baшe Mнeниe</LEGEND>

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

Этот недостаток можно устранить, используя специальный тип тега <INPUT> . Если в этом теге установить атрибут TYPE="file", то пользователь увидит на экране текстовое поле для ввода имени файла, а рядом с ним будет расположена кнопка, при нажатии на которую откроется стандартное окно выбора файла. Имя выбранного файла будет автоматически введено в текстовое поле. Можно написать, например, так:

<LABEL FOR="Opinion-File">BBennTe имя файла с описанием вашего мнения: </LABEL><BR>

<INPUT TYPE="file" NAME="Opinion-File" SIZE="30">

Как видите, с помощью атрибута SIZE= здесь также можете задать ширину текстового поля.

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

<DIV CLASS="lft"> <Н1>Ваш отзыв о наших услугах</Н1>

<DIV ALIGN="center"> <TABLE WIDTH="75%"><TR><TD>

<FORM ACTION="http://cgi.lentyay.corn/guest.cgi" METHOD="post">

<FIELDSET Т1ТLЕ="Сведения о клиенге">

<LEGEND ALIGN="left">Paccжите о ce6e</LEGEND>

<DIV ALIGN="center">

<LABEL FOR="Name">Baшe имя:</LАВЕL>

<INPUT TYPE="text" NAME="Name" VALUE="AHOHИM" SIZE="30">

<BR><BR>

<LABEL FOR="Age">Baш возраст :</LABEL>

<SELECT NAME="Age" SIZE="1">

<OPTION VALUE="10">Meнee 20

<OPTION VALUE="20">20&ndash;30

<OPTION VALUE="30">30&ndash;40

<OPTION VALUE="40">40&ndash;50

<OPTION VALUE="50">50&ndash;60

<OPTION VALUE="60">6onee 60 </SELECT>

<BR><BR>

<LABEL FOR="Sex">Baш пол:</LABEL>

<INPUT TYPE="radio" NAME="Sex" VALUE="М">Мужской

<INPUT TYPE="radio" NAME="Sex" VALUE="F">Женский

<BR><BR>

<LABEL FOR="Interestsl">Baши интересы:<BR></LABEL>

<INPUT TYPE="checkbox" NAME="Interestsl" VALUE=" Computers ">Kомпьютеры

<INPUT TYPE="checkbox" NAME="Interests2" VALUE="Sports">Cnopт

<INPUT TYPE="checkbox" NAME="Interests3" VALUE="Art">Иcкyccтво

<INPUT TYPE="checkbox" NAME="Interests4" VALUE="Science">Hayкa

</DIV> </FIELDSET>

<BR>

<FIELDSET ТIТLЕ="Ваше мнение">

<LEGEND ALIGN="left">Bame мнение</LEGEND>

<DIV ALIGN="center">

<LABEL FОR="Орtion-Fi1е">Введите имя файла с описанием вашего мнения :</LABEL>

<BR>

<INPUT TYPE="file" NAME="Opinion-File" SIZE="30">

<BR><BR>

<LABEL FOR="Opinion-Text">Или просто выскажите свое мнение прямо здесь: </LABEL>

<BR>

<TEXTAREA COLS="30" ROWS="4" NAME="Opinion-Text" STYLE="vertical-align: middle; "></TEXTAREA>

</DIV>

</FIELDSET>

<BR>

<DIV ALIGN="center">

<INPUT TYPE="submit" VALUE="Отправить">

<INPUT TYPE="reset" VALUE="Очистить форму"> </DIV>

</FORM> </TD></TR></TABLE> </DIV> </DIV>

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

Рис. 7.4. Логическое объединение элементов формы.

Другие элементы формы

Итак, запомним, что тег <INPUT> может использоваться в формах для создания самых разных элементов управления. Вид элемента зависит от значения атрибута TYPE= этого тега. Некоторые из этих значений мы уже рассмотрели. Теперь давайте просто перечислим оставшиеся:

<INPUT TYPE="password">

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

<INPUT TYPE="button">

А такая запись создает кнопку произвольного назначения. В отличие от кнопок типа Submit (Отправить) или Reset (Сброс), при нажатии на эту кнопку ничего не произойдет, если не написан соответствующий обработчик события (с обработчиками событий мы познакомимся в следующем разделе). Тег <lNPUTTYPE="button"> во многом аналогичен рассмотренному в главе 3 тегу <BUTTON> . Однако, в отличие от последнего, он не позволяет отображать на кнопках графику и другие нестандартные объекты. С другой стороны, будучи элементом формы, он доступен для обработки в броузере Netscape 4.

<INPUT TYPE="hidden">

А этого поля на экране вообще не будет видно. Обычно его используют для передачи на сервер какой-либо пояснительной информации (значение этого поля, несмотря на его невидимость, все равно передается на сервер).

Итак, закончим на этом “формальную” часть этой главы и перейдем к примерам того, как элементы веб-страниц могут реагировать на действия пользователя.


7.2

7.2. Страница, управляемая при помощи мыши

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

Помните, как в примерах Главы 4 мы изменяли цвет гиперссылки при наведении на нее мыши? Это происходило с помощью псевдокласса :hover. Однако этот псевдокласс пока что определен только для тега <А> . А как быть, если мы хотим изменить цвет обычного текста при наведении на него мыши?

Рассмотрим, как это делается. Допустим, мы написали небольшую тесто вую страницу.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТIТLЕ>Обработка событий мыши</ТIТLЕ>

</HEAD>

<BODY> Этот текст не изменит свой цвет. Этот текст изменит свой цвет, если навести на него мышь! Этот текст не изменит свой цвет.

</BODY>

</HTML>

Реакция на наведение

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

<DIV>Этот текст изменит свой цвет, если навести на него мышь!</DIV>

Чтобы при наведении мыши что-нибудь произошло, нужно добавить обработчик событий onMouseOver:

<DIV onMouseOver="">Этот текст изменит свой цвет, если навести на него мышь</DIV>

Итак, обработчик добавлен, однако пока он ничего не делает. В кавычки нужно поместить то действие, которое он должен выполнить. А что он дол жен сделать? Изменить цвет этого блока <DIV> , например, на красный. Доступ к свойствам текущего элемента осуществляется с помощью ключевого слова this:

<DIV onMouseOver="this.style.colors'red">Этот текст изменит свой цвет, если навести на него мышь!</DIV>

Если теперь открыть эту страницу в броузере, то при наведении указателя мыши на вторую строку текста, цвет строки действительно изменится на красный. Однако, один раз изменившись, он так и останется красным. Чтобы при уводе указателя мыши со строки цвет изменился обратно на черный, добавим обработчик событий, реагирующий на увод указателя. Он называется onMouseOut:

<DIV onMouseOver="this.style.color"'red'" onMouseOut="this.style.color='black'">Этот текст изменит свой цвет, если навести на него мышь!</DIV>

Теперь при наведении указателя мыши на эту строку, ее цвет изменится на красный, а при уводе указателя — обратно на черный. Можно также использовать и доступ по названию элемента. Например, если установить в этом блоке атрибут ID="text1", то можно будет написать так:

<DIV ID="textl" onMouseOver="textl.style.color='red'" onMouseOut="textl.style.color='black'">Этот текст изменит цвет, если навести на него мышь!</DIV>

<DIV ID="textl" onMouseOver="document.all.textl.style.color='red'" onMouseOut="document.all.textl.style.color”'black'">Этот изменит свой цвет, если навести на него мышь!</DIV>

Обратите внимание на то, что внутри кавычек расположен текст, написанный на языке JavaScript. Чтобы не загромождать текст HTML-документа, можно заранее определить соответствующие функции в разделе <HEAD>:

<HEAD>

<ТIТLЕ>Обработка событий мыши</ТIТLЕ>

<SCRIPT LANGUAGE="JavaScript">

function change() { document, all. textl. style. color="red";

} .function change2() { document.all.textl.style.color="black";

} //--> </SCRIPT> </HEAD>

а при определении обработчиков событий писать только имена функций:

<DIV ID="textl" onMouseOver="change()" onMouseOut="change2()">Этот текст изменит свой цвет, если навести на него мышь!</DIV>

Результат будет тот же, что и в прошлый раз.

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

<DIV ID="text2">Этот текст изменит свой цвет, если мышь навести на вторую строку!</DIV>

а потом соответствующим образом изменить функции:

function change() { document.all.textl.style.color="red";

document.all.text2.style.color="green";

} function change2() {

document.all.textl.style.coior="black";

document.all.text2.style.color="black"; }

Теперь при наведении мыши на вторую строку ее цвет будет изменяться на красный, а цвет третьей строки — на зеленый. К сожалению, здесь начинают сильно сказываться различия между броузерами. Доступ через метод documental! будет работать в Internet Explorer, но не сработает в Netscape. Чтобы этот пример мог работать в Netscape 6, необходимо доступ через метод document, all заменить на доступ через метод document. getElementByld( ). А как быть, если мы хотим, чтобы этот пример работал и в Internet Explorer, и в Netscape 6?

Учет различий между броузерами

Такие вопросы обычно решаются не просто. Но в данном случае мы можем осуществить проверку версии броузера и, в зависимости от ее результата, присвоить переменной textl либо значение document.all.textl, либо значение document.getElementByld("text1"). А затем в функциях замены цвета просто подставлять эту переменную. То же самое можно проделать и с переменной text2. Только нужно не забыть заранее определить эти переменные:

var text1, text2; function brws()

{ if (navigator.appName!="Net scape")

{ textl=document.all.textl; text2=document.all.text2 ;

} else { textl=document.getElementById("textl") ;

text2=document.getElementById("text2"); } }

Теперь необходимо сделать так, чтобы нагла функция brws( ) выполнялась сразу после загрузки страницы. Для этого установим в теге <BODY> обработчик событий, реагирующий на загрузку элемента. Он называется onLoad:

<BODY onLoad="brws( )">

Посмотрим, что у нас получается в целом.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transional//EN">

<HTML>

<HEAD>

<TITLE>06pa6oткa событий мыши (1Е4, NN6)</TITLE>

<SCRIPT LANGUAGE="JavaScript">

var textl, text2; function brws()

{ if (navigator.appName!="Netscape") ( textl=document.all.textl; text2=document.all.text2;

} else {
textl=document.getElementById("textl") ;
text2=document.getElementById("text2") ;

} } function change () { textl.style.color="red"; text2.style.color="green";

}

function change2()
{ textl.style.color="black"; text2. style.
color="blacl<";

} //-->

</SCRIPT>

</HEAD>

<BODY onLoad="brws()"> Этот текст не изменит свой цвет.

<DIV !D="textl" onMouseOver="change() " onMouseOut="change2()">

Этот текст изменит свой цвет, если

навести на него мышь!

</DIV> <DIV !D="text2">Этот текст изменит свой цвет, если мышь навести на вторую строку!</DIV>

</BODY>

</HTML>

Результат можно увидеть на рис. 7.5. Теперь этот пример работает и в броузере Internet Explorer, и в броузере Netscape 6. Конечно, хотелось бы создавать такие страницы, которые бы работали по крайней мере в этих двух броузерах, потому что в Netscape версии 4 поддержка динамических страниц вообще очень слабая. Однако это не всегда возможно. В этой книге в дальнейшем все примеры будут ориентированы на броузер Internet Explorer версии 4 и выше (если специально не оговорено обратное).

Рис. 7.5. Страница, на которой цвет строк может изменяться

Кнопки, влияющие на вид страницы

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

Для начала в соответствии с требованиями HTML 4.0 заменим атрибуты BGCOLOR= и BACKGROUND= тега <BODY> на соответствующие стилевые свойства:

<STYLE> BODY { background-color: #BFFFBF;

background-image: url("Images/gradi.jpg"); }

</STYLE>

Что же касается тега <BODY> , то ему желательно присвоить имя для облегчения доступа к его свойствам:

<BODY ID="doc">

Теперь добавим сверху две кнопки: одну для выключения фонового рисунка, а другую — для смены цвета фона на белый:

<DIV ALIGN="center"> <INPUT TYPE="button" VALUE="Убрать фоновый рисунок">

<INPUT TYPE="button" VALUE="Сделать фон белым"> </DIV>

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

function noBg() { document.all.doc.style.backgroundlmage='none'; }

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

Теперь нужно сделать так, чтобы наша функция noBg() выполнялась при щелчке мыши на первой из кнопок. Для этого надо в соответствующий тег кнопки добавить обработчик событий, реагирующий на щелчок мыши. Он называется onClick:

<INPUT TYPE="button" VALUE="y6paть фоновый рисунок" onClick="noBg ()">

Аналогично создадим функцию для смены цвета фона на белый:

function colChangeO ( document.all.doc.stylе.backgroundColor='white'; } и добавим ко второй кнопке обработчик события onClick:

<INPUT TYPE="button" VALUE="Cделать фон белым" onClick="colChange()">

Если теперь открыть эту страницу в броузере, то при нажатии на кнопку Убрать фоновый рисунок градиентный фоновый перелив исчезнет, уступив место зеленоватому цвету, а при нажатии на кнопку Сделать фон белым фон страницы действительно станет белым.

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

<INPUT
TYPE="button" NAME="buttl"
VALUE="Убрать фоновый рисунок"
onClick="noBg()">

<INPUT
TYPE="button"
NAME="butt2"VALUE="Сделать фон
белым" onClick="colChange()">

Можно было, разумеется, использовать и атрибут ID= вместо NAME=. Для того чтобы изменить надпись на первой кнопке, достаточно изменить значение ее атрибута VALUE=:

document.all.butti.value='Вернуть фоновый рисунок';

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

function noBg() {
if (document.all.doc.style.backgroundlmage="none") {
document.all.doc.style.backgroundlmage='none' ;

document.all.butti.value='Вернуть фоновый рисунок';

} else { document.all.doc.style.backgroundlmage="url('Images/gradi.jpg')"'; document.all.butti.values'Убрать фоновый рисунок'; } }

В первой строке функции мы сравниваем значение стилевого свойства backgroundlmage со значением none, и если оно с ним не совпадает, то, значит, фоновый рисунок есть. В этом случае мы присваиваем этому спой ятву значение none и изменяем надпись на кнопке на Вернуть фоновый рису (нок. В противном же случае мы присваиваем свойству backgroundlmage значение, содержащее имя файла фонового рисунка, и изменяем надпись на кнопке на первоначальную.

Таким же способом мы переделываем функцию colChange(). Сначала проверим значение свойства backgroundColor, и, если оно не совпадает со значением white (белый), присвоим ему это значение, а в противном случае присвоим первоначальное значение #BFFFBF. Одновременно будем изме нять и надпись на второй кнопке: function colChange() { it (document.all.doc.style.backgroundColor!='white'){ document.all.doc.style.backgroundColor"'white' ;

document.all.butt2.value='Сделать фон зеленым';

}

else { document.all.doc.style.backgroundColor='#BFFFBF' ; document.all.butt2,value='Сделать фон белым'; } } Теперь пользователь может с помощью первой кнопки включать и вык- лючать фоновый рисунок по желанию, а с помощью второй — переклю чать цвет фона с зеленоватого на белый и обратно. Однако остался еще один нерешенный вопрос. Дело в том, что если включен фоновый рису- нок, то переключение цвета фона не дает никакого видимого результат”, что может смутить пользователя. Поэтому, пока включен фоновый рису нок, лучше вообще не давать возможности нажимать на вторую кнопку. Internet Explorer позволяет сделать ее недоступной с помощью атрибут DISABLED. Поскольку изначально фоновый рисунок включен, установим этот атрибут сразу же при создании второй кнопки:

<INPUT
TYPE="button" NAME="butt2"
VALUE="Сделать фон белым" DISABLED
onClick="colChange()">

А в функцию noBg( ) следует включить сброс атрибута DISABLED для второй кнопки при выключении фонового рисунка и, соответственно, уста новку этого атрибута при включении фона:

function noBg() { if (document.all.doc.style.backgroundlmage!="none") {

document.all.doc.style.backgroundlmage='none';
document.all.butti.value='Вернуть фоновый
рисунок'; document.all.butt2.disabled=false; } else {
document.a
11.doc.style.backgroundlmage="url('Images/gradi.jpg')";
document.all.butti.value='Убрать фоновый
рисунок'; document.all.butt2.disabled=true; } }

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

<!DOCTYPE HTML
PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML> <HEAD> <TITLE>CKА3KА</TITLE>
<STYLE> BODY { background-color: #BFFFBF; background-image:
url("Images/gradi.jpg") ; } </STYLE>
<SCRIPT> <!--function noBg() { if
(document.all.doc.style.backgroundlmage!="none") {
document.all.doc.style,backgroundlmage='none' ;
document.all.butti.value='Вернуть фоновый
рисунок'; document.all.butt2.disabled=false; } else {

document.all.doc.style.backgroundlmage= "url('Images/gradl.jpg')";

document, all .buttl .value='Убрать фоновый рисунок'; document.all.butt2.disabled=true;

} }

function colChangef)

{ if (document.all.doc.style.backgroundColor!='white')

{ document.all.doc.style.backgroundColor='white' ;

document.all.butt2.value='Сделать фон зеленым'; }

else {
document.all.doc.style.backgroundColor='#BFFFBF''
document.all.butt2.value='Сделать фон белым';

}

}

//-->

</SCRIPT>

</HEAD>

<BODY ID="doc"> <DIV ALIGN="center">

<INPUT
TYPE="button" NAME-"buttl"
VALUE="y6paть фоновый рисунок"
onClick="noBg()">

<INPUT
TYPE="button" NAME-"butt2
VALUE="Сделать фон белым" DISABLED
onClick="colChange()">

</DIV>

<BR>

<DIV ALIGN="center">

<IMG SRC="Images/hr2.gif" WIDTH="508" HEIGHT="18" BORDER="0" ALT""></DIV>

<DIV ALIGN="center">

<IMG
SRC="Images/skazk.gif" WIDTH="359"
HEIGHT="150" BORDER="0"
ALT="CKA3KA"><BR>

<H2> О ТОМ, КАК ИВАН-ДУРАК ПОСРАМИЛ ЦАРЯ ГOPOXA</H2></DIV>

<DIV
ALIGN="justify"><IMG
SRC="Images/bukvical.gif" WIDTH="121"
HEIGHT="111" BORDER="0"
ALIGN="LEFT" ALT="Д">

авным-давно жил-был на белом свете царь Горох. И были у него поля гороховые, и леса гороховые, и степи гороховые, и даже моря гороховые. Все было гороховым. И была у него дочь &mdash; царевна Горошина. Волосы у нее были зеленые, и глаза тоже зеленые, потому что с детства только на горох и смотрела. Но вообще-то она была писаной красавицей. Все придворные царские, и бояре, и пажи, и лакеи, и даже слуги и повара дворцовые были по уши влюблены в нее. Но была у царевны Горошины одна странность &mdash; любила она смотреть по ночам на далекую звезду Адырлетавру, которая светила в том царстве так ярко, что обычные люди на той стороне, где звезда была, даже окон в домах не делали. <BR><BR>

<FONT SIZE="+3">............................................

</FONT><BR><BR>

Тут и сказке конец, а кто слушал &mdash; молодец, ему пряник в награду и кило мармеладу.<BR>&nbsp;</DIV>

<DIV
ALIGN="center"><IMG SRC=" Images/hr2
.gif" WIDTH="508" HEIGHT="18"
BORDER="0" ALT=""></DIV>

</BODY>

</HTML>

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

Рис. 7.6. Веб-страница, на которой “бесполезная” в данный момент кнопка недоступна

Заметим, что приведенная выше страница будет работать только в Internet Explorer. Ее можно заставить работать и в Netscape 6 тем же способом, который мы применили в предыдущем примере — путем написания функции, присваивающей одной и той же переменной либо значение document.all, либо document.getElementByld, в зависимости от типа броузера:

var doc, butti, butt2; function brws(),

{ if (navigator.appName!""Netscape") ( buttl=dofc.ument .all. butti; butt2=docwnent.all.butt2; doc=docunysnt. all. doc;

}

else (

buttl=document.getElementById("buttl") ;

butt2=document.getElementById("butt2") ;

doc=document.getElementById("doc") ;

} }

Затем следует переписать функции noBg() и colChange( ), убрав из них обра щение document.all:

function noBg() { if (doc.style.backgroundlmage!="none")

{
doc.style.backgroundlmage='none' ; butti,value='Вернуть
фоновый рисунок'; butt2.disabled=false;

} else {

doc.style.backgroundlmage="url('Images/gradi.jpg')";

butti.value='Убрать фоновый рисунок'; butt2.disabled=true;

}

function colChange()

{ if (doc.style.backgroundColor!='white')

{
doc.style.backgroundColor='white' ; butt2.value='Сделать
фон зеленым';

} else { doc.style.backgroundColor='#BFFFBF' ;

butt2.value='Сделать
фон белым'; }

}

И, наконец, назначить выполнение функции brws() сразу после загрузки страницы:

<BODY ID="doc" onLoad="brws()">

Теперь наш код будет одинаково работать и в Internet Explorer 4+, и в Netscape 6. Что касается Netscape 4, то, если постараться, можно заставить эту стра ницу работать и там, но это будет довольно сложно. В Netscape 4 нельзя получить доступ непосредственно к свойствам тега <BODY> , однако броузер можно “обмануть”, использовав либо тег <LAYER> и коллекцию document.layers, либо свойства типа document.body.bgColor. Давайте лучше не будем этим заниматься, тем более что смотреть нашу страницу в Netscape 4 все равно можно, просто обе наши кнопки в нем вообще не отобразятся (этот броу зер не воспринимает теги <INPUT> вне элемента <FORM> ).

Реализация операций перетаскиванием

Итак, мы рассмотрели несколько основных обработчиков событий. Однако существуют и другие события мыши. Например, веб-страница может отдельно реагировать на нажатие кнопки мыши, на ее отпускание и даже на ее движение. Для чего это может понадобиться? Одно из возможных применений — это реализация так называемой технологии drag-and-drop, (проще говоря — перетаскивания экранных объектов с помощью мыши. Для иллюстрации рассмотрим несложный пример.

Предположим, вы хотите проиллюстрировать на своей странице знаменитую игру Лойда “Пятнадцать”, например так, как показано на рис. 7.7. Нужно, вроде бы, сначала просто задать стиль для текста:

<STYLE> BODY { . background-color: #979797; color: #FEFEFE; text-align: center;

font-weight: bold; font-size: 30рх;

font-family: sans-serif; . } </STYLE>

затем вывести на экран заголовок; потом создать центрированный блок ( <DIV> ) с фиксированной шириной и высотой, а также небольшим отсту- пом сверху, заданным с помощью стилевого свойства margin-top:

<DIV ALIGN="center" STYLE="width: 400px; height: 400px; margin-top: 25px;">

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

Рис. 7.7. Страница, иллюстрирующая игру “Пятнадцать”

<TABLE
BGCOLOR="#COCOCO" WIDTH="100%"
CELLSPACING="0" CELLPADDING="0"
BORDER="1">

и в каждую ячейку этой таблицы поместить заранее подготовленное изображение плашки с цифрой', например, вот так:

<TD
WIDTH="25%" ID="cl"><IMG
SRC="Images/digitl.gif" WIDTH="100"
HEIGHT="100" BORDER="0"
ALT="1"></TD>

Вообще говоря, поскольку ширина (и высота) рисунков определены в 100 пикселов, атрибут WIDTH= указывать для тега <TD> совсем не обязательно. Что же касается атрибута ID=, то мы здесь указали его с расчетом на то, что плашки придется переставлять, и тогда потребуется доступ к ячейкам таблицы.

Все это замечательно, если исходная позиция задана изначально. Однако предположим, что мы хотим дать пользователю возможность самому рас ставить плашки. Пусть в начале игры все они расположены вне игрового поля. Можно даже расположить их друг на друге. Пользователь при этом должен иметь возможность перетянуть мышью каждую из плашек на одну из клеток игрового поля. Для этого придется сделать три вещи.

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

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

И, в-третьих, при отпускании кнопки мыши нужно оставить рисунок на том месте, куда он был передвинут.


Динамическое управление позиционированием элементов

Чтобы все это реализовать, придется использовать позиционирование объектов на экране. Прежде всего, определим позицию блока, в который будет включена таблица (“игровое поле”):

<DIV STYLE="width: 400px; height: 400px; position: absolute;

top: 100px;">

Вероятно, вы обратили внимание на то, что сейчас мы задали только пози- цию блока <DIV> по вертикали (с помощью стилевого свойства top). А каким должно быть свойство left (позиция по горизонтали)? Хотелось бы, чтобы наше игровое поле располагалось по центру, но ведь мы не знаем ширину окна броузера пользователя!

К счастью, в Internet Explorer есть возможность определить ширину окна броузера, прочитав значение свойства document.body.clientWidth. После этого все уже просто. Сначала разделим это значение на 2, чтобы получить пози цию в центре экрана. Поскольку наша таблица будет иметь ширину 400 пикселов, для вычисления позиции ее левого края вычтем из позиции центра экрана половину ширины таблицы, то есть 200:

tstart=document.body.clientWidth/2-200;

В данном примере мы присвоили вычисленное значение переменной tstart. Поскольку оно будет неоднократно использоваться в дальнейшем, полезно объявить эту переменную как глобальную (то есть не внутри какой-либо функции, а в самом начале кода JavaScript). Теперь осталось дать имя нашему блоку <DIV>:

<DIV ID="maintab" STYLE="width: 400px; height: 400px; position: absolute; top: 100px;">

и присвоить его свойству left вычисленное значение:

<SCRIPT LANGUAGE”"JavaScript" TYPE="text/javascript">

var tstart; function mainpos()

{ tstart document.body.clientWidth/2-200;

document.all.maintab.style.left=tstart; )

//--> </SCRIPT>

Приведенная выше функция mainposO должна выполняться сразу после загрузки страницы (иначе пользователь увидит таблицу неизвестно где). Поэтому установим в теге <BODY> уже знакомый нам обработчик событий on Load:

<BODY onLoad="mainpos() ">

Вот теперь при загрузке страницы (а точнее, сразу после нее) наш блок <DIV> , содержащий таблицу, будет отцентрирован. Но как быть с ячейками таблицы? Ведь мы знаем, что если даже в тегах <TD> указать ширину и высоту, эти требования будут восприняты броузером лишь как рекомендательные, и на экране просто не отобразится ни одна ячейка. Если же поместить в ячейки неразрывные пробелы, то строки таблицы получатся мизерной высоты (рис. 7.8).

puc. 7.8. Указание в тегах <TD> высоты и ширины, не приводит к желаемому результату

Что же делать? Есть один прием, который позволяет сделать минималь- ную ширину и высоту ячейки таблицы такой, какой нужно именно нам, а не такой, какой захочет броузер. Дело в том, что при наличии рисунка в ячейке таблицы броузер обязательно расширит границы ячейки так, чтобы рисунок был виден целиком. Поэтому создадим очень маленький графи ческий файл, содержащий целиком прозрачный рисунок (в нашем при- мере был использован прозрачный рисунок размером 4х3 пиксела). Рисунок такого маленького размера будет загружаться очень быстро, прак- тически не влияя на скорость загрузки страницы. Однако в соответствую- щем ему теге <IMG> установим ширину и высоту (с помощью атрибутов WIDTH= и HEIGHT=) такими, какими мы хотим видеть ширину и высоту ячейки таблицы. Таким образом, мы получим как бы пустую ячейку с заданными минимальными размерами!

Вот как можно это сделать в нашем примере:

<TD><IMG SRC="Images/diafanol.gif" WIDTH="100" HEIGHT="100"</TD>

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

<IMG
ID="pl" SRC="Images/digitl.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="1" STYLE="position: absolute; top: 120px;
left: 10px;">

<IMG
ID="p2" SRC="Images/digit2.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="2" STYLE="position: absolute; top: 220px;
left: 10px;">

<IMG
ID="p3" SRC="Images/digit3.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="3" STYLE="position: absolute; top: 320px;
left: 10px;">

<IMG
ID="p4" SRC="Images/digit4.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="4" STYLE="pOsition: absolute; top: 420px;
left: 10px;">

<IMG
ID="p5" SRC°"Images/digit5.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="5" STYLE="position: absolute; top: 520px;
left: 10px;">

<IMG
ID="p6" SRC="Images/digit6.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="6" STYLE="position: absolute; top: 120px;
left: 30px;">

<IMG
ID="p7" SRC="Images/digit7.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="7" STYLE="position: .absolute; top: 220px;
left: 30px;">

<IMG ID="p8" SRC="Images/digit8.gif" WIDTH="100" HEIGHT="100" t BORDER="0" ALT="8" STYLE="position: absolute; top: 320px; left: 30px;">

<IMG
ID="p9" SRC="Images/digit9.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="9" STYLE="position: absolute; top: 420px;
left: 30px;">

<IMG
ID="plO" SRC="Images/digitl0.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="10" STYLE="position: absolute; top: 520px;
left: 30px;">

<IMG
ID="pll" SRC="Images/digitll.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="11" STYLE="position: absolute; top: 120px;
left: 50px;">

<IMG
ID="pl2" SRC="Images/digitl2.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="12" STYLE="position: absolute; top: 220px;
left: 50RX;">

<IMG
ID="pl3" SRC="Images/digitl3.gif"
WIDTH="100" HEIGHT="100"
BORDER="0"'\ALT="13" STYLE="position:
absolute; top: 320px; left: 50rix;">

<IMG
ID="bl4" SRC="Images/digitl4.gif"
WIDTH="100" HEIGHT="100" BORDER="01-
ALT="14" STYLE="position: absolute; top: 420px;
left: 50px;">

<IMG
ID="pl5" SRC="Images/digitl5.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="15" STYLE="position: absolute; top: 520px;
left: 50px;">

Результат показан на рис. 7.9. Пока это выглядит не очень красиво, поскольку на виду у пользователя оказался третий ряд плашек (с цифрами от 11 до 15), а остальные расположились под ним. Лучше было бы, если бы наверху оказались плашки с 1 по 5.

Можно, конечно, решить эту проблему, присвоив каждой плашке свое значение стилевого свойства z-index, однако проще изменить порядок сле дования тегов <IMG>. Если сначала написать теги для рисунков плашек с 11 по 15, затем — с 6 по 10 и в конце — с 1 по 5, то при наложении рисун ков те, которые были объявлены позже, окажутся сверху. Кроме того, вполне можно разместить рисунки чуть выше по вертикали:

<IMG
ID="pll" SRC="Images/digitll.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="11" STYLE="position: absolute; top: 60px;
left: 50px;">

<IMG
ID="pl2" SRC="Iniages/digitl2.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="12" STYLE="position: absolute; top: 160px;
left: 50px;">

<IMG
ID="pl3" SRC="Images/digitl3.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="13" STYLE="position: absolute; top: 260px;
left: 50px;">

<IMG
ID="pl4" SRC="Images/digitl,4.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="14" STYLE="position: absolute; top: 360рх;
left: 50px;">

<IMG
ID="pl5" SRC="Images/digitl5.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="15" STYLE="position: absolute; top: 460px;
left: 50px;">

Рис. 7.9. Исходная позиция для расстановки плашек

<IMG
ID="p6" SRC="Images/digit6.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="6" STYLE="position: absolute; top: 60px;
left: 30px;">

<IMG
ID="p7" SRC="Images/digit7.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="7" STYLE="position: absolute; top: 160px;
left: 30px;">

Результат показан на рис. 7.10. Теперь, наконец, подготовительная работа закончена, и нужно реализовать обработку событий, как говорилось выше.

Реакция на нажатие кнопки

Сначала добавим в тег <BODY> обработчики событий, реагирующие на нажатие кнопки мыши (не на щелчок, который состоит из нажатия и отпускания левой кнопки, а именно на нажатие) — onMouseDown, на отпускание кнопки — onMouseUp и на движение указателя мыши — onMouseMove:

<BODY
onLoad="mainpos()" onMouseDown="down_it()"
onMouseUp="up_it()"
onMouseMove="move_it()">

Рис. 7.10. Изменение порядка следования позиционированных элементов <IMG> позволяет изменить их расположение в третьем измерении

Теперь осталось написать функции, которые мы так лихо назначили обработчикам событий. Сначала давайте займемся нажатием кнопки мыши (onMouseDown).

Прежде всего, нам надо определить, была ли нажата кнопка мыши на рисунке одной из плашек. Если нет, то ничего делать не нужно. Как проверить это условие? В Internet Explorer 4+ источник каждого события записывается в свойство window.event.srcElement. Но что нам это дает? Ведь нужных нам рисунков целых 15, и у каждого есть свое уникальное имя (свойство ID=). Неужели придется сравнивать свойство window.event.srcElement id с каждым именем?

Мы совсем забыли, что каждый рисунок плашки представляет собой тег <IMG>. Поэтому мы можем сравнить свойство window.event.srcElement.tagName, содержащее названия тега-источника события, со словом IMG, и в случае удачи перейти к дальнейшим действиям:

function down_it() { if(window.event.srcElement.tagName=="IMG") { // какие-то действия } } Стоп! Но ведь, кроме рисунков плашек, у нас еще есть прозрачный рисунок, расположенный в каждой из шестнадцати ячеек таблицы! А вот его-то нам никуда передвигать совсем не нужно. При этом от рисунков плашек его отличает только свойство SRC=. Придется сравнить это свойство со значением Images/diafanol.gif, и продолжать дальнейшую работу функции лишь в том случае, если совпадение не обнаружится.

Однако если мы напишем:

if ( (window, event. srcElement. tagName s ""IMG") && (window.event.srcElement.src!="Images/diafanol.gif")) {

// какие-то действия }

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

Оказывается, свойство window.event.srcElement.src в любом случае содержит указание на абсолютное местоположение файла рисунка. Так, например, если эти опыты мы проводим на локальном компьютере, то значением window.event.srcElement.src будет полный путь доступа к файлу, включающий имя диска и родительские папки. Поскольку при разработке страницы, скорее всего, еще нельзя точно предсказать этот путь доступа, да и проверить работу страницы на локальном компьютере тоже нелишне, придется поступить по другому. Воспользуемся тем, что каково бы ни было абсолютное расположение файла, значение window.event.srcElement.src все равно будет заканчиваться его именем — в нашем случае diafanol .gif. то есть символы с 13-го по 5-й от конца строки будут заведомо содержать значение diafanol. Поскольку длина любой строки всегда содержится в ее свойстве length, то мы можем выделить из полного названия файла нужные нам символы, начиная от length-12 и кончая length-4. Выделение части строки можно произвести методом substring:

if((window.event.srcElement.tagName=="IMG")&& (window.event.srcElement.src.substring (window.event.srcElement.src.length-12, window.event.srcElement.src.length-4)!="diafanol")) {

// какие-то действия }

Вот теперь все заработает правильно. Правда, строка условия выглядит очень громоздко. Мы не рекомендуем писать такие строки, поскольку через какое-то время с ними будет трудно разбираться, если вдруг понадобится что-то изменить. Например, в нашем случае можно определить локаль ную переменную 1 и присвоить ей значение window.event.srcElement.src.length. Тогда строка условия будет выглядеть хоть немного компактней:

if((window.eventssrcElement.tagName="IMG") && (window, event .'SrcElement. src.substring (1-12,1-4) != "diafanol"”

Какие же действия нужно осуществить внутри этой функции? Если вы еще не забыли, нам нужно “привязать” рисунок плашки к указателю мыши. Для этого достаточно определить глобальную переменную (мы назвали ее moving), и присваивать ей всегда имя рисунка, который необхо димо передвигать. Если никакой рисунок передвигать не нужно (кнопка мыши отпущена или нажата не на рисунке плашки), можно присвоить переменной moving значение " " (пустая строка). В самом начале сценария эту переменную можно объявить так:

var moving"";

а в теле функции down_it(), которую мы сейчас пишем, будем присваивать ей значение, содержащее имя того рисунка, на котором пользователь щелкнул мышью:

moving=window.event.srcElement.id;

Реакция на перемещение мыши

В принципе, наша функция down_it() уже справляется со своими обязанностями. Теперь давайте займемся функцией moveit( ), которая будет вызываться при движении мыши.

Эта функция должна прежде всего проверить, нужно ли передвигать какой- либо рисунок. Как вы помните, его имя содержится в переменной moving. Так что нужно сначала сравнить значение переменной moving с пустой стро кой и в случае совпадения не предпринимать никаких действий:

function move it() { if (moving!="") { // какие-то действия

} }

Теперь давайте подумаем, что должно быть сделано, если переменная moving содержит имя рисунка, который нужно передвинуть. Очевидно, для того чтобы его передвинуть, нужно изменить его стилевые свойства left и top в соответствии с расположением указателя мыши. Текущее положение указателя мыши можно узнать, прочитав значения свойств window.event.clientX и window.event.clientY.

— Стоп! — скажете вы. — А как узнать, как должен располагаться рису нок относительно указателя мыши? Ведь пользователь может щелкнуть и в центре рисунка, и с краю, и в любом другом месте. Значит, в функции down_it(), которую мы считали уже законченной, нужно еще вычислить координаты указателя мыши относительно рисунка?

— Правильно! Это обязательно нужно сделать, если применять эту технологию для перетаскивания крупных объектов. Но в нашем примере мы позволим себе упростить задачу, воспользовавшись тем, что наши плашки имеют относительно небольшие размеры. При таких размерах будет вполне нормально, если при перетягивании рисунка указатель мыши будет находиться посередине его. Поскольку рисунки наши имеют размер 100х100, нам остается вычесть 50 из каждой координаты указателя мыши и при своить эти значения свойствам left и top рисунка:

document.all[moving].style.pixelLeft=window.event.clientX-50; document.all[moving].style,pixelTop=window.event.clientY-50;

Обратите внимание на то, что для обращения к объекту по его имени, содержащемуся в переменной, необходимо использовать квадратные скобки, то есть писать document.all[moving], а не document.all. moving. В противном случае броузер не сможет найти нужный объект и выдаст сообщение об ошибке . Кроме того, обратите внимание на то, что для корректного изменения координат в Internet Explorer необходимо использовать свойства pixelLeft и pixelTop вместо left и top.

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

window.event.cancelBubble = true; window.event.returnValue = false;

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

window.event.returnValue = false;

тo рисунки начнут “тормозиться” уже при небольшом перемещении, после чего броузер может вообще не распознать отпускание кнопки мыши. Мы сейчас не будем вдаваться в подробности того, почему так происходит. Однако запомните, что эти две короткие строчки при обработке событий мыши часто помогают избежать многих неприятностей. Если у вас что-то не получается, проверьте, а не “всплывает” ли какое-нибудь нежелательное событие? И не пытается ли броузер делать что-то “свое” вместо назначенных вами операций?

Реакция на отпускание кнопки

Теперь давайте займемся функцией up_it(), выполняющейся при отпускании кнопки мыши. Собственно говоря, все, что нужно сделать — это проверить, передвигался ли какой-нибудь объект (то есть, содержит ли переменная moving какое-либо имя) и, если это так, присвоить этой переменной пустую строку, что будет означать “освобождение” рисунка: function up_it() ( if (moving!="") moving="";

Однако хорошо бы еще расположить рисунок не где попало, а точно в ячейке таблицы. Поскольку в этом случае его координаты относительно начала таблицы должны быть кратны 100, это довольно легко осуществить. Для этoгo достаточно округлить его до ближайшей сотни. Для округления можно использовать встроенный метод Math.round. Понятно, что он округляет не до сотен, а до целых чисел, поэтому текущие координаты рисунка перед округлением придется разделить на 100, а после округления — умно жить на 100. Кроме того, не забывайте, что кратность 100 мы определяем относительно начала таблицы, которое равно tstart по горизонтали и 100 но вертикали. Поэтому перед делением на 100 нужно еще вычесть из горизонтальной координаты значение tstart, а в конце снова его прибавить. Вот что у нас получается:

document.all[moving].style.pixelLeft= Math.round;(window.event.clientX-50-tstart)/100)*100+tstart+l;

document.all[moving].style,pixelTop= Math.round((window.event.clientY-50)/100)*100+1;

Как видите, все довольно просто. Здесь мы прибавили к каждой коорди нате еще по единице, чтобы рисунки не налезали на сетку таблицы. Кстати, ширину ячеек таблицы (то есть, прозрачного рисунка diafanol.gif) в этом случае тоже необходимо немного скорректировать. Поскольку каждая ячейка таблицы имеет со всех сторон бордюр шириной в 1 пиксел, придется сделать ширину самих ячеек равной не 100, а 98:

Кроме того, неплохо было бы, если бы наши рисунки располагались точно, но сетке таблицы только в ее пределах, а в других частях экрана принимали бы свободное положение. Для этого можно перед округлением досотен проверить, расположен ли рисунок внутри таблицы (или хотя бы рядом с ней):

i f (window.event.clientX>=tstart-50&&window.event,clientY>=50) {

document.all[moving].style.pixelLeft= Math.round((window.event.clientX-50-tstart)/100)*100+tstart+l;

document.all[moving].style,pixelTop= Math.round((window.event.clientY-50)/100)* 100+1;

}

И, наконец, еще один штрих. При перемещении некоторых рисунков может возникнуть ситуация, когда перемещаемый рисунок будет проходить как бы под другим, пропадая на время из видимости. Чтобы этого не возникало, давайте добавим в функцию down_it() еще такую строку:

document.all[moving].style.zlndex=5;

Поскольку у всех остальных элементов значение z-index не изменялось (и, следовательно, равно нулю), мы добиваемся того, что перемещаемый рисунок никогда не будет перекрыт другими объектами. Естественно, при окончании перемещения рисунка ему нужно возвратить исходное значение z-index. Для этого в функцию up_it() добавим строку

document.a 11[moving].style.zlndex=0; Итак, давайте посмотрим, что же у нас получается.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Иrpa 15</TITLE>

<STYLE> BODY { background-color: #979797; color: #FEFEFE;

text-align: center; font-weight: bold;

font-size: 30рх; font-family: sans-serif; }

</STYLE>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

var tstart; var moving="";

function mainpbs( )

{ tstart=document.body.clientWidth/2-200;

document. a.is .rnaintab. style. left=tstart;

function down_it()

{ var 1==window. event. srcElement. src.length;

if((window.event.srcElement.tagName="IMG")&&

(window.event.srcElement.src.substring(1-12,1-4)!= "diafanol"))

{ moving=window.event.srcElement.id;

document.all[moving].style.pixelLeft=window.event.clientX-50; document.all[moving].style.pixelTop=window.event.clientY-50;

document.all[moving].style.zlndex=5; } } function up it() { if (moving!="") {

if (window.event.clientX>=tstart-50&& window.event.clientY>=50) {

document.all[moving].style.pixelLeft= Math.roundf(window.event.clientX-50-tstart)/100)*100+tstart+1;

document.all[moving].style,pixelTop= Math.round((window.event.clientY-50)/100)*100+1;

} document.all[moving].style.zlndex=0; moving=""; }

} function move it() { if (moving!="")

{
document.all[moving].style.pixelLeft=window.event.clientX-50;
document.all[moving].style.pixelTop==window.event.clientY-50 ;

} event.cancelBubble = true; event.returnValue = false; }

//—>

</SCRIPT>

</HEAD>

<BODY
enLoad="mainpos()" опМouseDown="down it()"
onMouseUp="up_it()"
onMouseMove="move_it()">

Расставьте плашки перетаскиванием с помощью мыши

<DIV ID="maintab" STYLE="width: 400px; height: 400px; position: absolute; top: 100px;">

<TABLE
BGCOLOR="#COCOCO" WIDTH="100%"
CELLSPACING="0" CELLPADDING="0"
BORDER="1">

<TR>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD> </TR> <TR>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD> </TR> <TR>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD> </TR> <TR>

<TD><IMG SRC="Images/diafanol.gif" HIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

</TR> </TABLE> </DIV>

<IМG
ID="p11" SRC="Images/digitll.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="11" STYLE="position: absolute; top: 60px;
left: 50px;

<IMG
ID="pl2 SRC="Images/digitl2.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
AtlT="12" STYLE="position: absolute; top: 160px;
left: 50px;

<IMG
ID="p13 SRC-"Images/digitl3.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="13" STYLE="position: absolute; top: 260px;
left: 50px;">

<IMG
ID="pl4" SRC="Images/digitl4.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="14" STYLE="position: absolute; top: 36Орх;
left: 50px;">

<IMG
ID="pl5" SRC="mages/digitl5.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="15" STYLE="position: absolute; top: 460px;
left: 50px;">

<IMG
ID="p6" SRC="Images/digit6.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="6" STYLE="position: absolute; top: 60px;
left: 30px;">

<IMG
ID="p7" SRC="Images/digit7.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="7" STYLE="position: absolute; top: 160px;
left: 30px;">

<IMG
ID="p8" SRC="Images/digit8.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="8" STYLE="position: absolute; top: 260px;
left: 30px;">

<IMG
ID="p9" SRC="Images/digit9.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="9" STYLE="position: absolute; top:
ЗбОрх; left: 30px;">

<IMG
ID="plO" SRC="Images/digitl0.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="10" STYLE="position: absolute; top: 460px;
left: 30px;">

<IMG
ID="pl" SRC="Images/digitl.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="1" STYLE="position: absolute; top: 60px;
left: 10px;">

<IMG
ID="p2" SRC="Images/digit2.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="2" STYLE="position: absolute; top: 160px;
left: 10px;">

<IMG
ID="p3" SRC="Images/digit3.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="3" STYLE="position: absolute; top: 260px;
left: 10px;">

<IMG
ID="p4" SRC="Images/digit4.gif"
WIDTH="100" KEIGHT="100" BORDER="0"
ALT="4" STYLE="position: absolute; top:
ЗбОрх; left: 10px;">

<IMG
ID="p5" SRC="Images/digit5.gif"
WIDTH="100" HEIGHT="100" BORDER="0"
ALT="5" STYLE="position: absolute; top: 460px;
left: 10px;">

</BODY>

</HTML>

Результат представлен на рис. 7.11. В принципе, в такую игру уже можно по-настоящему играть. Конечно, этот код можно еще упростить. Правильно, зачем шестнадцать раз повторять тег вставки прозрачного рисунка? Давайте заменим его вложенным циклом JavaScript:

for (var k=l; k<=4; k++) { document.write("<TR>") ;

for (var m=l; m<=4; m++) document.write('<TD> <IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"> </TD>') ;

document.write("</TR>");

}

Рис. 7.11. Реализация технологии drag-and-drop: пользователь может перетаскивать плашки с помощью мыши

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

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

К сожалению, приведенная выше страница будет работать только в Internet Explorer. Если необходимо, чтобы она работала также и в Netscape 6, придется приложить некоторые усилия. Дело в том, что помимо различий в син таксисе доступа к элементам, о котором мы уже говорили (в Netscape используется конструкция document.getElementByld вместо document.all), различия существуют также и в обработке событий. В частности, вместо глобального объекта event в Netscape необходимо использовать временную переменную, которой будет передаваться значение объекта event. Кроме того, вместо свойства srcElement используется свойство target, а свойство returnValue вообще не поддерживается. Выше мы приводили примеры того, как написать код, работающий в обоих популярных броузерах. Вы можете в качестве упраж нения попробовать это сделать и для данного примера, однако из-за обработки событий мыши это будет сложнее, чем в предыдущих случаях.


7.3

7.3. Страница, управляемая с клавиатуры

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

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

Реакция на нажатие клавиши

Давайте попробуем реализовать эту возможность. Для начала назначим элементу <BODY> обработчик событий, реагирующий на нажатие клавиш. Он называется onKeyPress:

<BODY onKeyPress="press()">

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

Обратите внимание на то, что для организации доступа к каждой букве (и к началу файла) нам не придется прикладывать никаких дополнительных усилий! Ведь мы уже ранее создали соответствующие якоря с помо щью тега <А>, и хотя они и не имеют атрибута ID=, у них есть атрибут NAME=, который тоже можно использовать для доступа к элементам.

Итак, при нажатии на клавишу нужно проверить, какая буква была нажата. Это можно сделать, прочитав значение свойства window event keyCode. Оно равно ASCIIJ-коду нажатой клавиши. Например, если нажата клавиша с русской буквой а, то значение свойства window event keyCode равно 1072, то есть коду этой буквы.

Таким образом, мы можем использовать оператор switch, чтобы назначить различные действия в зависимости от кода нажатой клавиши:

switch(window.event.keyCode) { case 1072: // какие-то действия case 1073: // какие-то действия и т.д.

Чтобы прокрутить страницу к заданному элементу, можно воспользоваться методом scrolllntoView( ). Например, если мы напишем

document.all.BukvaA.scrolllntoView() ;

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

Учет раскладки клавиатуры

Теперь надо подумать еще о том, что пользователь может забыть переклю- читься на русскую раскладку клавиатуры. Давайте не будем заставлять его это делать. Поскольку мы знаем, что на одной клавише с русской бук вой а расположена буква f, на одной клавише с б — знак < и т. д., мы можем осуществить проверку не только кодов букв а, б, в, г, д, е, но и кодов сим волов f, <, d, u, I, t. Можно написать, например, так: case 1072: case 102: document.all.BukvaA.scrolllntoViewO; break; case 1073: case 44: document.all.BukvaB.scrollIntoView() ; break;

В этом случае прокрутка к букве а осуществится, даже если пользователь нажмет клавишу с буквой а или f, забыв переключиться на русскую рас-кладку клавиатуры. Аналогично можно осуществить прокрутку и к дру- им буквам. Чтобы при нажатии какой-нибудь иной клавиши вернуться началу файла, можно присвоить это возвращение случаю “default”:

default”: document.all.Top.scrollIntoView(); break;

Вот, собственно говоря, и все. Но чтобы изучить еще некоторые обработчики событий, давайте добавим еще эффект уменьшения яркости текста во время нажатия клавиши. Так обращают внимание пользователя на то, что “что-то происходит” (а именно: прокрутка). Для этого нужно использо-вать обработчики событий, реагирующие раздельно на нажатие и на отпускание клавиши. Они называются, соответственно: onKeyDown и onKeyUp:

<BODY
onKeyPress="press ()"
onKeyDown="this.style.color='gray'" onKeyUp="this
style.color='black'">

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

Подсказка для читателя

И в качестве последнего штриха давайте добавим подсказку для пользователя. Пусть, когда он начнет прокручивать страницу вручную (с помощью полосы прокрутки), в строке состояния отобразится такая подсказка: Вы можете перемещаться к нужной букве, используя клавиатуру'. Это можно сделать, используя обработчик событий, реагирующий на прокрутку страницы (есть и такой!). Он называется onScroll:

<BODY onKeyPress="press ()" onKeyDown="this.style.color='gray'" 'Вы можете перемещаться к нужной букве, используя клавиатуру''">

Кстати, один раз появившись, подсказка так и останется в строке состояния, но в данном случае в этом нет ничего плохого. Строка состояния — место не самое заметное, так что подсказка в ней выглядит вполне корректно. Вот чего делать не надо, так это использовать бросающиеся в глаза методы типа alert:

<BODY onKeyPress="press ()" onKeyDown="this.style.color='gray'" onKeyUp="this.style.color='black'" onScroll="alert('Вы можете перемещаться к нужной букве, используя клавиатуру'')">

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

Ладно, давайте посмотрим, что у нас получилось, здесь введено еще несколько усовершен ствований, связанных с использованием таблицы стилей. Например, нет необходимости каждый термин заключать в теги <В> и </В> . Вместо этого для тега <DT> заранее определено стилевое свойство font-weight: bold;.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">

<HTML>

<HEAD>

<TITLE>Словарь терминов</ТIТLЕ>

<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html" CHARSET="windows-1251">

<STYLE> BODY ( background-color: #EAEAEA; color: black;

} A:link, A:active, A:visited { color: #7A3F51;}

DT { font-weight: bold; } </STYLE>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

<!--

function press () switch(window.event.keyCode)

{ case 1072: case 102: document.all.BukvaA.scrollIntoView() ;

break; case 1073: case 44: document.all.BukvaB.scrollIntoView() ;

break; case 1074: case 100: document.all.BukvaV.scrollIntoView () ;

break; case 1075: case 117: document.all.BukvaG.scrollIntoView() ;

document.all.BukvaD.scrollIntoView() ;

break; case 1077: case 116: document.all.BukvaE.scrollIntoView() ;

break; default:

document.all.Top.scrollIntoView() ; break;

} }

//-->

</SCRIPT>

</HEAD>

<BODY onKeyPress="press()" onKeyDown="this.style.color='gray'" onKeyUp="this.style.color='black'" onScroll="window.status= 'Вы можете перемещаться к нужной букве, используя клавиатуру!'">

<Н1><А NAME="Top">Cловарь терминов</А></Н1>

<HR ALIGN="left" WIDTH="40%">

<НЗ> <А HREF="#BukvaA">A</A>

<А HREF="#BukvaB">Б</A> <А HREF="#BukvaV">B</A>

<А HREF="#BukvaG">Г</A> <А HREF="#BukvaD">Д</A>

<А HREF="#BukvaE">E</A> </НЗ> Для перемещения к соответствующей букве вы можете использовать клавиатуру

<HR ALIGN="left" WIDTH="40%">

<Н1><А NAME="BukvaA">A</A></Hl>

<DL> <DT><A NAME="avtentich">AБTEHTИЧECKИЙ КАДАНС</А>

<DD>кадансовый оборот, в котором заключительная тоническая гармония предваряется доминантовой

<DT>

<A NAME="aliquot">AЛИKBOTHЫE СТРУНЫ</А>

<DD>резонирующие струны, к которым исполнитель не прикасается во время игры

<DT><A NAME="atakta">ATAKTA</A>

<DD>гармонический элемент на басу нижнего или верхнего вводного тона

</DL> <SMALLXA HREF="#Top">B начало</А>

</SМАLL> <HR ALIGN="'left" WIDTH="40%">

<H1><A NAME="BukvaB">Б</A></Hl>

<DL> <DT><A NAME="bagatel">БАГАТЕЛЬ</A>

<DD>небольшая нетрудная для исполнения пьеса <DT>

<A NAME="bartok">БAPTOKOBCKOE ПИЦЦИКАТО</А>

<DD>сильный щипок струны с последующим ударом о струны о гриф <DT>

<A NAME="bonang">БОНАНГ</A> <DD>Ha6op из 10-12 гонгов разного размера </DL>

<SMALL><A HREF="#Top">B Haчaлo</A></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaV">B</A></Hl> <DL>

</DL> <SMALL>

<A HREF="#Top">B Haчaлo</A></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaG">Г</A></Hl>

<DL> </DL> <SMALL><A HREF="#Top">B Haчano</A></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaD">Д</A></Hl>

<DL> </DL>

<SMALL><A HREF="#Top">B Haчaлo</A></SMALL>

<HR ALIGN="left" WIDTH="40%">

<H1><A NAME="BukvaE">E</A></Hl>

<DL></DL> <SMALL>

<A HREF="#Top">B начало</A></SMALL>

</BODY>

</HTML>

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


7.4

7.4. Динамическое отображение текста веб-страницы

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

Вообще-то говоря, в разделе 7.2 мы уже один раз немного изменяли текст, но это был текст на кнопке. Если помните, тогда мы меняли надписи Сде лать фон белым и Сделать фон зеленым. Надпись на кнопке изменялась при помощи значения атрибута VALUE= тега <INPUT> . Однако что делать, если текст, подлежащий изменению, не является кнопкой?

Давайте рассмотрим такой пример. Предположим, нам надо несколько усовершенствовать “Домашнюю страницу Сергея Сергеева”, которую мы создавали в Главах 1, 2 и 4. К примеру, нам хочется, чтобы сначала на странице отображался только вступительный текст и текст первого рас сказа. А при нажатии на ссылку вместо текста первого рассказа появлялся бы текст второго рассказа и т. д.

(Оказывается, это осуществить очень легко! Заключим для начала текст первого рассказа в блок <DIV> и присвоим ему уникальное имя:

< DIV ID="rasskaz"> <Н2>ИВАН-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ<ВР> OPAN STYLE="font-style: italic; ">cкaзкa</SPAN></H2>

<DIV STYLE="text-align: right;"> <DIV CLASS="epig"> Ну, погоди!.. <DIV CLASS="pdps">(Из мультфильма)</DIV> </DIV> </DIV> <BR>

<DIV CLASS="аЬ">Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный. Однако тоскливо было у него на душе - как встанет утром с постели царской, так и начнет горевать, и горюет до вечера.</DIV>

<DIV CLASS="аЬ">Долго ли, коротко ли ...</DIV>

<DIV CLASS="аЬ">И они жили долго и счастливо и умерли в один день.</DIV>

<HR> </DIV> Теперь вместо ссылки на второй рассказ напишем просто

<SPAN onClick="show_hammer()">Рассказ &laquo;МОЛОTOK&raquo;</SPAN>

Как видите, теперь, если пользователь щелкнет мышью на словах Рассказ “Молоток”, то будет выполнена функция show_hammer(). По нашей задумке, она должна заменить текст сказки на текст рассказа “Молоток”.

Вспомним, что весь текст сказки был заключен в блок <DIV> . А у любого блока <DIV> , как и у большинства других элементов, имеется свойство innerHTML, значение которое содержит весь HTML-код данного элемента! Это означает, что если мы изменим значение этого свойства, изменится и HTML-V.OJS,, а значит, и текст, содержащийся на странице. Наша функция show_hammer() может выглядеть, например, вот так:

function show_hammer() { document .all. rasskaz . innerHTML=' <H2>MOЛOTOK<BR>

<SPAN STYLE="font-style: italic ;">paccкaз</SPAN></H2>

<DIV STYLE="text-align: right;">

<DIV CLASS="epig">Mы кузнецы, и дух наш молод.<DIV CLASS="pdps">(Из песни) </DIV></DIV></DIV><BR>

<DIV CLASS="аЬ">Это случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии. . . (Здесь располагается текст рассказа) </DIV>;

}

Как видите, эта функция выполняет всего одно действие — присваивает свойству document.all. rasskaz. innerHTML значение, содержащее длинную-предлинную строку. В этой строке содержится весь HTML-код, рассказа “Молоток” .

Имитация гиперссылок

Но как пользователь узнает, что на словосочетании Рассказ “Молоток” нужно щелкнуть, как на гиперссылке, для появления текста рассказа на кране? Для этого придется либо действительно оформить его как гипер-ссылку, то есть заключить в тег <А HREF='#'>, либо просто подчеркнуть его, а также изменить вид указателя мыши над ним:

<SPAN STYLE="text-decoration: underline; cursor: hand;" onClick="show hammer()">Рассказ &laquo;MonoTOK&raquo;</SPAN>

Можно сюда же добавить и изменение цвета, и тогда с точки зрения пользователя эта строка вообще не будет ничем отличаться от гиперссылки. Помните, в предыдущей “версии” этой страницы мы с вами определяли для гиперссылок коричневатый цвет с помощью таблиц CSS:

A:link,A:visited { color: #634438; }

Теперь же наша мнимая гиперссылка на самом деле является элементом <SPAN>.Mы могли бы просто заменить в приведенном выше определении стиля A:link, A:visited на SPAN. Но поскольку этот элемент может использоваться еще для чего-нибудь на той же странице, лучше определим для него специальный класс, допустим, под названием Ink:

.Ink { color: #634438; }

Кстати, подчеркивание и изменение формы указателя мыши можно также внести непосредственно в таблицу стилей:

.Ink { color: #634438; text-decoration: underline; cursor: hand; } Теперь осталось написать сам код нашей мнимой гиперссылки:

<SPAN CLASS="ink" onClick="show_hammer()">Рассказ &laquo;МОЛОTOK &raquo;</SPAN>

Итак, теперь эта страница приобрела внешний вид, показанный на рис. 7.11. После щелчка на мнимой гиперссылке Рассказ “Молоток” ее вид изменится (см. рис. 7.12).

Вот исходный текст этой страницы.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТITLE>Домашняя страница Сергея Сергеева.</TITLE>

<STYLE>

<!--

BODY { background-color: #BABAAO; color: rgb(29,29,24);

Рис. 7.12. Щелчок на “гиперссылке” изменяет текст в нижней части страницы

Рис. 7.13. Та же страница после щелчка на “гиперссылке”

} Н1,Н2 { text-align: center;

} .Ink ( color: #634438; text-decoration: underline; cursor: hand;

} HR ( margin-top: 24px; width: 75%;

) DIV.epig { text-align: justify; font-size: smaller; width: 130;

} DIV.pdps { font-style: italic; text-align: right;

} DIV.ab { text-align: justify; text-indent: 2em; } --> </STYLE>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

<!--

function show_hammer()

{ document. all. rasskaz . innerHTML='

<H2>MOЛOTOK<BR>

<SPAN STYLE="font-style: italic;">paccкaз</SPAN></H2>

<DIV
STYLE="text-align: right; "><DIV
CLASS="epig">Mы кузнецы, и дух наш
молод.<DIV CLASS="pdps">(Из песни)
</DIV>

</DIV>

</DIV><BR>

<DIV CLASS="аЬ">Это случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа) </DIV>';

} //-->

</SCRIPT> </HEAD>

<BODY> <Н1>Домашняя страница Сергея Сергеева</Н1>

<DIV STYLE="text-align: center;">Сказка &laquo;Иван-царевич и серый заяц&гаquо;&nbsp;

<SPAN CLASS="lnk" onClick="show_hammer()">Рассказ &laquo ;МОЛОTOK&raquo;</SPAN></DIV>

<BR>

<DIV STYLE="font-size: larger; ">

<SPAN STYLE="font-weight: bold;"> Сергей CepreeB</SPAN> &mdash; писатель-авангардист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.<ВR><ВR> Некоторые его рассказы вы можете прочитать прямо здесь.</DIV> <HR>

<DIV ID="rasskaz">

<Н2>ИВАН-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ<ВR>

<SPAN STYLE="font-style: italic;">CАKЗKА</SPAN></H2>

<DIV STYLE="text-align: right;"> <DIV CLASS="epig"> Ну, погоди!..

<DIV CLASS="pdps">(Из мультфильма)</DIV> </DIV> </DIV> <BR>

<DIV CLASS="аЬ">Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный. Однако тоскливо было у него на душе -как встанет утром с постели царской, так и начнет горевать, и горюет до вечера.</DIV>

<DIV CLASS="аЬ">Долго ли, коротко ли ...</DIV>

<DIV CLASS="ab">И они жили долго и счастливо и умерли в один день.</DIV>

<HR> </DIV> </BODY> </HTML>

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

Произвольный выбор текста

Однако в таком виде эта страница представляется еще не совсем завер шенной, поскольку, когда на экране отобразится текст рассказа “Молоток”, вернуть обратно текст сказки не удастся (если, конечно, пользователь

сообразит нажать в броузере кнопку Reload (Обновить), но рассчитывать это некорректно). Поэтому надо сделать еще одну мнимую гиперссылку, которая загружала бы текст сказки. Поскольку стиль уже определен, сде-лать это совсем нетрудно:

<SPAN CLA3S="lnk" onClick="show_ivan()">Сказка &1аquо;Иван- царевич и серый заяц&гадио;</SPAN>

Одновременно нужно написать функцию show_ivan(), во всем аналогичную функции show_hammer(). Она должна просто заменять значение свойства document.all.rasskaz.innerHTML обратно на текст сказки:

function show_ivan'() { document.all.rasskaz.innerHTML='

<Н2>ИВАН- ЦАРЕВИЧ И СЕРЫЙ ЗAЯЦ<BR>

<SPAN STYLE="font-style: italic;"> сказка</SPAN></Н2>

<DIV STYLE="text-align: right; ">

<DIV CLASS="epig">Hy, погоди!..

<DIV CLASS="pdps">(Из мультфильма </DIV></DIV>

</DIV><BR><DIV CLASS="аЬ">Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный. Однако тоскливо было у него на душе - как встанет утром с постели царской, так и начнет горевать, и горюет до вечера.</DIV><DIV СЬАЗЗ="аЬ">Долго ли, коротко ли. . ,</DIV><DIV CLASS="ab">H они жили долго и счастливо и умерли в один день .</DIV><HR>';

обращаем ваше внимание на то, что .HTML-код, находящийся внутри функции, должен представлять собой одну строку, то есть в нем не должно ододержаться ни одного служебного символа перевода строки, которые мы для удобства иногда вставляем в обычный HTML-текст. Если такие символы в нем останутся, то интерпретатор JavaScript “подумает”, что мы просто написали одну незавершенную строку, а потом еще и начали дру-гую строку с неопределенного объекта. Соответственно, при этом появятся вообщения об ошибках, и страница вообще не будет “работать”.

Честно говоря, определять такие длинные строки в “теле” функции можно, нo неудобно, и потому не принято. Лучше сразу определить переменные, содержащие эти строки, и из функций обращаться уже к этим перемен-

var hammer='<H2>MOnOTOK<BRXSPAN STYLE="font-style: italic;"> paccкaз</SPAN></H2>

<DIV STYLE="text-align: right; ">

<DIV CLASS="ерig">Мы кузнецы, и дух наш молод.<DIV CLASS="pdps">(Из песни) </DIV></DIV></DIV><BR>

<DIV CLASS="аЬ">Это случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа)

var ivan=' <Н2>ИВАН-ЦАРЕВИЧ И СЕРЫЙ 3AЯЦ <BR>

<SPAN STYLE="font-style: italic; ">CKА3KА</SPAN></H2>

<DIV STYLE="text-align: right;">

<DIV CLASS="epig">Hy, погоди!..

<DIV CLASS="pdps">(H3 мультфильма)</DIV> </DIV></DIV><BR>

<DIV CLASS="аЬ">Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный. Однако тоскливо было у него на душе - как встанет утром с постели царской, так и начнет горевать, и горюет до вечера. </DIV><DIV CLASS="аЬ">Долго ли, коротко ли. . .</DIV><DIV CLASS="ab">И они жили долго и счастливо i умерли в один день .</DIV><HR>';

function show_hammer() { document.all.rasskaz.innerHTML=hammer; function show__ivan() ( document.all.rasskaz.innerHTML=ivan; }

Это, во-первых, намного нагляднее, а кроме того, если одна из этих “ строк ” вдруг потребуется еще в какой-либо функции, то можно будет легко к ней обратиться по имени переменной, не вводя всего этого “крокодила” заново. Кстати, теперь, когда у нас есть две мнимые гиперссылки на оба текста, можно первоначально не отображать на экране ни один из них:

<DIV ID="rasskaz"> </DIV>

Такое начало будет смотреться эффектнее (рис. 7.14), а заодно мы избавимся

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

<BODY onLoad="show ivan()">

Рис. 7.14. На этой странице изначально не видно ни одного из рассказов

Теперь еще одна маленькая деталь. Хорошо бы сделать так, чтобы мнимая

гиперссылка на тот текст, который уже отображается на экране, в выглядела бы, как гиперссылка. Этого легко достичь, поскольку вид определен как класс в таблице стилей. Итак, определим еще один класс для “посещаемой в данный момент” части страницы:

. Ink() { color: rgb(29,29,24) ;

text-decoration: none; cursor: default;

} В данном случае мы определили внешний вид текущего текста таким же, как вид обычного текста, однако можно было придумать и какое-нибудь особое начертание). Теперь модифицируем наши функции show_ivan() и show_hammer() так, чтобы они изменяли класс (а значит, и внешний вид) наших мнимых гиперссылок: function show_hammer()

{ document, all .rasskaz . innerHTML=hanimer;

document.all.ivanink.className="lnk";

document.all.hammerlnk.className="lnk0";

} function show_ivan() { document.all.rasskaz.innerHTML=ivan;

document.all.ivanink.className="lnk0";

document.all.hammerlnk.className="lnk";

} Обратите внимание на то, что для доступа к атрибуту CLASS= нужно исполь- повать свойство className, а не class, поскольку слово class является заре- зервированным ключевым словом JavaScript.

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

Во-первых, при наличии, например, 100 сменяющихся текстов, при щел чке на одной из мнимых гиперссылок нужно определить, какой из них нужно вернуть внешний вид гиперссылки (класс Ink). Придется опреде лить глобальную переменную и каждый раз записывать в нее имя исполь зованной ссылки. Например, если назвать эту переменную, допустим, oldink, то наша функция show_hammer() приобретет такой вид: function show_hammer()

{ document.all.rasskaz.innerHTML=hammer;

document.all[oldink].className="lnk";

document.all.hammerlnk.className="lnkO";

oldlnk='hammerlnk'; }

При этом лучше сразу при инициализации присвоить переменной oldlnk имя одного из идентификаторов, чтобы не делать лишнюю проверку, не является ли oldink пустой строкой. Да и вообще, если сменяющихся текстов много, лучше не писать для отображения каждого отдельную функ цию, а просто написать обобщенную функцию show(), которая может полу чать идентификатор ссылки в качестве аргумента или даже просто брать его из значения свойства window.event.srcElement.

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


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

Помимо рассмотренного здесь свойства innerHTML, каждый элемент веб страницы имеет еще три похожих свойства:

• innerText — то же, что и innerHTML, однако не может содержать HTML теги;

• outerHTML — то же, что и innerHTML, но включает в себя открывающий и закрывающий теги данного элемента, а также вложенные элементы:

• и, наконец, outerText — то же, что и outerHTML, однако не может содер жать HTML-tens..

Другими словами, свойства innerText и innerHTML каждого элемента содер жат только внутренний текст этого элемента, а свойства outerText и outerHTM L — весь текст элемента, включая вложенные элементы и теги самого элемента. При этом innerText и outerText не содержат HTML.-форматирования, innerHTML и outerHTML могут его содержать. Из всех этих свойств у начина ющих обычно вызывает вопросы только outerText. Однако оно используется довольно редко. Изменив его, можно практически убрать со страницы весь элемент.

Кроме того, существуют удобные методы для вставки текста и HTML-sop,” на страницу. Они называются insertAdjacentText и insertAdjacentHTML. Давайте рассмотрим такой пример. Допустим, мы хотим, чтобы на “домашней странице Сергея Сергеева” через минуту после нажатия на любую из наших мнимых “гиперссылок” и, соответственно, отображения текста одного из рассказов, перед ним появлялась красная надпись “Ну что, нравится?”

Потом к ней можно еще добавить разные кнопки типа ДА, НЕТ, НЕ ОЧЕНЬ

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

Добавление дополнительных надписей

Для этого можно сделать следующее. Определим соответствующий стиль.

Н3 { text-align: center; color: red; }

В нашем примере для запроса к пользователю мы используем тег <НЗ>. После этого вставим нашу надпись таким образом:

document.all.rasskaz.insertAdjacentHTML("AfterBegin", '<H3>Hy что, нравится?<НЗ>');

Здесь используется метод insertAdjacentHTML, что позволяет вставлять не только текст, но и HTML-тети. Аргумент AfterBegin означает, что вставля-емый код будет помещен в начало блока <DIV ID='rasskaz'> . Если бы мы напи-сали BeforeEnd, то код был бы вставлен в конец блока. Кстати, методы lnsertAdjacentText и insertAdjacentHTML позволяют вставить текст (и HTML-код) не только внутрь какого-либо элемента, но и непосредственно перед и им или после него! Для этого используются аргументы BeforeBegin и, соответственно, AfterEnd. Как вы уже поняли, в качестве второго аргумента используется строка с текстом или HTML-кодом, который надо вставить.

Остальное уже просто. Добавим в каждую функцию отображения текста при введенную выше строку в сочетании с установкой таймера — setTimeout:

setTimeout("document.all.rasskaz.insertAdjacentHTML ('AfterBegin','<H3>Hy что, нравится?<НЗ>') ", "60000");

Правда, это еще не все. Если оставить страницу в таком виде, то таймер включит метод добавления текста через минуту после щелчка на мнимой гипересылке, даже если пользователь за это время успеет щелкнуть на другой, а это нами не задумывалось. Поэтому во время щелчка на каждой мнимой гиперссылке следует останавливать предыдущий таймер. Для этого достаточно определить глобальную переменную:

var timer; И присвоить ей значение запущенного таймера:

time=setTimeout("document.all.rasskaz.insertAdjacentHTML ('AfterBegin','<H3>Hy что, нравится?<НЗ>') ", "60000");

Тогда для его остановки достаточно будет написать следующее:

clearTimeout(timer); В тот момент таймер будет остановлен.

И так давайте еще раз посмотрим на текст получившейся страницы. В ней использована одна функция show() для отображения любого из текстов. Обратите внимание на то, что при ее написании использован тот факт, что имя переменной, содержащей текст каждого рассказа, если к нему приба- вить окончание Ink, совпадает с именем соответствующей мнимой гипер- ссылки. Подобный разумный выбор имен позволяет передавать функции не два параметра (ivanink и ivan), а только один, что экономит время и ресурсы компьютера. В данном случае это не столь существенно, поскольку раз мер страницы невелик, но в некоторых случаях может сыграть большую роль.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТITLЕ>Домашняя страница Сергея Сергеева.</TITLE>

<STYLE>

<!--

BODY { background-color: #BABAAO;

color: rgb(29,29,24); } H1,H2 { text-align: center;

} H3 { text-align: center; color: red;

} .Ink { color: #634438;

text-decoration: underline;

cursor: hand;

} .Ink0 { color: rgb(29,29,24);

text-decoration: none;

cursor: default;

} HR { margin-top: 24px;

width: 75%;

DIV.epig { text-align: justify; font-size: smaller;

width: 130;

} DIV.pdps { font-style: italic;

text-align: right;

} DIV.ab { text-align: justify; text-indent: 2em; }

-->

</STYLE>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

<!--var oldlnk="ivanlnk";

var timer;

var hammer”'

<H2>MOЛTOK<BR><SPAN STYLE="font-style: italic; "> paccrap</SPAN></H2>

<DIV STYLE="text-align: right; ">

<DIV CLASS="epig">Mы кузнецы, и дух наш молод.

<DIV CLASS="pdps">(Из песни) </DIV></DIV></DIV> <BR>

<DIV CLASS="ab">Это случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа) </DIV>' ;

var ivan='<Н2>ИВАН-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ<ВR>

<SРАN STYLE="font-style: italic; ">CKА3KА</SPAN></H2><DIV STYLE="text-align: right;"><DIV CLASS="epig">Hy, погоди!..

<DIV CLASS="pdps"> (Из мультфильма) </DIV></DIV> </DIV><BR>

<DIV CLASS="ab">Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный. Однако тоскливо было у него на душе -как встанет утром с постели царской, так и начнет горевать, и горюет до вечера.</DIV><DIV CLASS="ab">Дoлгo ли, коротко ли... </DIV>

<DIV CLASS="ab">И они жили долго и счастливо и умерли в один день.</DIV><НR>';

function show(arg)

{ clearTimeout(timer) ;

document.all.rasskaz.innerHTML=eval(arg);

document.all[oldink].className="lnk";

oldlnk=arg+'Ink'; document.all[oldink].className="lnk0";

timer=setTimeout("document.all.rasskaz.insertAdjacentHTML ("AfterBegin",'<H3>Hy что, нравится?<НЗ>') ", "60000");

}

//-->

</SCRIPT>

</HEAD>

<BODY>

<Н1>Домашняя страница Сергея Сергеева</Н1>

<BR>

<DIV STYLE="font-size: larger;">

<SPAN STYLE="font-weight: bold;" Сергей CepreeB</SPAN> &mdash; писатель-авангардист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.

<BR><BR> Некоторые его рассказы вы можете прочитать прямо здесь.</DIV> <HR>

<DIV STYLE="text-align: center;">

<SPAN CLASS="lnk" ID="ivanlnk" onClick="show('ivan')">Сказка &laquo;Иван-царевич и серый заяц&гадио;</SPAN>&nbsp;

<SPAN CLASS="lnk" ID="hammerlnk" onClick="show('hammer')">Рассказ &laquo;МОЛОTOK&raquo;</SPAN> </DIV>

<HR>

<DIV ID="rasskaz"> </DIV>

</BODY>

</HTML>

Как видите, переменная oldink играет здесь еще одну, вспомогательную роль: ей присваивается результат “вычисления” имени мнимой гиперссылки, и она используется при обоих сменах ее стиля. Кроме того, в этом тексте используется функция eval(), которую мы с вами еще не рассматривали:

document.all.rasskaz.innerHTML=eval(arg) ;

Для чего она нужна? Давайте разберемся. Наша функция show() получает аргумент в виде текстовой строки:

onClick="show('ivan')"

Это сделано, чтобы легче было получить имя мнимой гиперссылки, про сто сцепив эту строку со строкой Ink (ivan + Ink = ivanink). Однако если Tenepь написать просто:

document.all.rasskaz.innerHTML=arg;

то содержимое блока <DIV ID='rasskaz'> будет заменено именем переменной. то есть строкой, поступившей в качестве аргумента. Использование функции

eval() здесь позволяет получить ссылку не на имя переменной, а на ее значение,

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

Рис. 7.12. Через минуту после появления текста рассказа возникает красная надпись “Ну что, нравится?”


7.5

7.5. Динамическое изменение графических элементов веб-страницы

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

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

Для примера модифицируем страницу со ссылками на поисковые машины, которую мы создали в главе 2. Сначала проведем некоторую подготовительную работу, а именно: нарисуем графические кнопки для гиперссылок, а также фоновый рисунок для всей страницы. Затем определим стиль для элемента <BODY>: BODY { text-align: center; background: url("Zmages/back7.jpg") ; }

Поскольку все содержимое нашей страницы будет размещено по ее центру, мы определили стилевое свойство text-align: center прямо для основного эле мента страницы < BODY>. Теперь, чтобы заголовок и пояснительный текс'1 не “терялись” на достаточно пестром фоне, определим для них “бордюры ” и фоновый цвет: H1 { border-color: #0063CE;

border-style: groover- border-width: thick;

padding: 5px; background-color: #ACEDFF; width: 16em;

} SPAN { border-color: #FF63CE; border-style: ridge;

border-width: medium; padding: 5px; background-color: #FCEDFF; width: 60%; font-size: 20px;

}

Имеется в виду, что мы заключим пояснительный текст в тег <SPAN> . Tenepь напишем основной текст страницы:

<BODY>

<Н1>ПОИСКОВЫЕ МАШИНЫ</Н1>

<SPAN>Если вы ищете в Интернате какую-либо информацию, вам помогут следующие сайты:</SPAN>

<BR><BR>

<А
HREF="http://www.altavista.corn"
TARGET="_blank"> <IMG
SRC="Images/altavista.Jpg" WIDTH="192"
HEIGHT="40" BORDER="0"
ALT="Altavista"></A><BR>

<A
HREF="http://www. yahoo, corn"
TARGET="_blank"> <IMG
SRC="Images/yahoo.jpg" WIDTH="147"
HEIGHT="40" BORDER="0"
ALT="Yahoo!"></A><BR>

<A
HREF="http://www.aport.ru"
TARGET="_blank"> <IMG
SRC="Images/aport.jpg" WIDTH="135"
HEIGHT="40" BORDER="0"
ALT="AnopT"></A><BR>

<A
HREF="http://www.yandex.ru"
TARGET="_blank"> <IMG
SRC="Images/yandex.jpg" WIDTH="129"
HEIGHT="40" BORDER="0"
ALT="Яndex"></A>

видите, пока что ничего нового. Результат показан на рис. 7.13. Согласясь, что это выглядит немного лучше, чем предыдущий вариант. Однако теперь нужно сделать то, ради чего мы все это начали — подсветить кнопки гиперссылок при наведении на них мыши.

Рис. 7.13. Страница графически оформленных гиперссылок

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

Управление “подсветкой” кнопок

Теперь назначим обработчику событий onMouseOver смену изображения. Собственно говоря, для этого нужно всего лишь изменить атрибут SRC= тегa <IMG>:

<IMG
SRC="'Images/altavista.jpg" WIDTH="192"
HEIGHT="40" BORDER="0"
ALT="Altavista"
onMouseOver="this.src='Images/altavista2.jpg'">

Теперь при наведении указателя мыши на кнопку Altavista вид кнопки изме нится, так как будет загружен другой рисунок. Точно таким же способом Iнужно сменить изображение обратно при выведении указателя мыши за пределы кнопки:

<IMG
SRC="Images/altavista.jpg" WIDTH="192"
HEIGHT="40" BORDER=0" ALT="Altavista"
onMouseOver="this.src='Images/altavista2.jpg'"
onMouseOut="this.src='Images/altavista.jpg'">

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

Рис. 7.14. На этой странице графические гиперссылки подсвечиваются при наведении на них указателя мыши

Можно, конечно, написать такую же конструкцию и для остальных трех кнопок. Однако, давайте реализуем более изящное решение: напишем одну функцию, которая будет менять файл рисунка для всех тегов <IMG>, имеющихся на странице. Точнее, функций будет две: одна для событии onMouseOver, а другая — для onMouseOut. Воспользуемся тем, что файлы рисунков “подсвеченных” кнопок имеют те же имена, что и файлы рисунков обычных кнопок, плюс цифра 2 (например: altavista.jpg — altavista2.jpg). Пусть первая функция, реагирующая на наведение мыши, просто встав ляет двойку в нужное место:

function changel() { if (window.event.srcElement.tagName="IMG")

window.event.srcElement.src= window.event.srcElement.src.substring(0, window.event.srcElement.src.length4)+"2"+ window.event.srcElement.src.substring (window.event.srcElement.src.length-4, window.event.srcElement.src.length) ;

}

Как видите, эта функция сначала проверяет, на какой объект, собственно, наведен указатель мыши, и если это элемент <IMG> , то в нужное место значения его атрибута SRC= вставляется цифра 2, а если это какой-нибудь другой элемент, то функция просто ничего не делает. Вроде все правильно, однако слишком громоздко — так сразу и не разберешься, что эта функция делает, да и при вводе таких строк легко ошибиться и потом долго и мучительно искать, почему выдаются сообщения об ошибках. Сократим этот год, присвоив значение window.event.srcElement временной переменной:

function changel() { var a=window.event.srcElement; if (a.tagName=="IMG")

a.src=a.src.substring(0, a.src.length-4)+"2"+ a.src.substring(a.src.length-4, a.src.length);

}

Вот это совсем другое дело — смотрится гораздо прозрачнее, а функционирует точно так же.

Теперь напишем аналогичную функцию, удаляющую двойку из значения атрибута

SRC=function
change2() { var a=window.event.srcElement; if
(a.tagName="IMG")

a.src=a.src.substring(0, a.src.length-5)+ a.src.substring(a.src.length-4, a.src.length);

}

Вам осталось только назначить обработчики событий. Поскольку мы не нем, для каких конкретно элементов их назначать и сколько, назначим объекту document (обратите внимание, что внутри функций не зря про наводится проверка на имя тега):

document.onmouseover=changel ;

document.onmouseout=change2;

последние две строки также должны находиться в блоке <SCRIPT> . Обратите внимание на отсутствие круглых скобок после имен функций! (Если скобки поставить, то это приведет к немедленному вызову функций, а нам можно только связать их имена с соответствующими событиями.) Теперь можно добавлять сколько угодно кнопок гиперссылок на эту страницу, загромождая ее большим количеством повторяющегося кода.

Предварительная загрузка графических объектов

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

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

типа Image:

var imgl=new
Image(); imgl.src='Images/altavista.jpg'; var img2=new Image();
img2.src='Images/altavista2. jpg';

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

Посмотрим, что у нас получилось в целом.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Страницца гиперссылок</TITLE>

<STYLE TYPE="text/css">

BODY { text-align: center- background: url("Images/back?.jpg") ;

} H1 { border-color: #0063CE;

border-style: groove;

border-width: thick;

padding: 5px; background-color:

#ACEDFF; width: 16em;

} SPAN { border-color:

#FF63CE;

border-style: ridge;

border-width: medium; padding: 5px;

padding: 5px;

background-color:

#FCEDFF;

width: 60%;

font-size: 20px;

} IMG { margin: 7px; }

-->

</STYLE>

<SCRIPT LANGUAGE""JavaScript" TYPE="text/javascript">

var imgl=new Image() imgl.src='Images/altavista.jpg';

var img2=new
Image() img2.src='Images/altavista2.jpg'; var img3=new Image()
img3.src='Images/yahoo.jpg'; var img4=new Image()
img4.src='Images/yahoo2.jpg'; var img5=new Image()
img5.src='Images/yandex.jpg'; var img6=new Image()
img6.src='Images/yandex2.jpg'; var img7=new Image()
img7.src='Images/aport.jpg'; var img8=new Image()
img8.src='Images/aport2.jpg';

function changel() { var a=window.event.srcElement; if (a.tagName=="IMG")

a.src=a.src.substring(0,a.sre.length-4)+"2"+ a.src.substring(a.sre.length-4, a.src.length);

} function change2() { var a=window.event.srcElement; if (a.tagName=="IMG")

a.src=a.src.substring(0,a.src.length-5) + a.src.substring(a.src.length-4, a.src.length) ;

}
document.onmouseover=changel; document.onmouseout=change2 ;
//--> </SCRIPT> </HEAD>

<ВОDY>

<Н1>ПОИСКОВЫЕ МАШИНЫ</Н1>

<SPAN>Если вы ищете в Интернете какую-либо информацию, вам помогут следующие сайты::<SPAN>

<BR><BR>

<А
HREF="http://www.altavista.corn"
TARGET="_blank"> <IMG
SRC="Images/altavista.jpg" WIDTH="192"
HEIGHT="40" BORDER="0"
ALT="Altavista"></A><BR>

<A HREF="http://www.yahoo.corn" TARGET="_blank">

<IMG SRC="Images/yahoo.jpg" WIDTH="147" HEIGHT="40" BORDER="0" ALT="Yahoo! "></A><BR>

<A HREF="http://www.aport.ru" TARGET="_blank">

<IMG
SRC="Images/aport.jpg" WIDTH="135"
HEIGHT="40" BORDER="0"
ALT="AnopT"></A><BR>

<A HREF="http://www.yandex.ru" TARGET="_blank">

<IMG
SRC="Images/yandex.jpg" WIDTH="129"
HEIGHT="40" BORDER="0"
ALT="Яndex"></A>

</BODY>

</HTML>

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


8

8. Размещение элементов на веб-странице и навигация по сайту

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

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

• использование фреймов;

• использование таблиц;

• и позиционирование независимых слоев.

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

8.1. Использование структуры фреймов

Формирование набора фреймов

Итак, начнем. Разделим нашу страницу на две части (два фрейма) — левую и правую. Вообще говоря, каждый фрейм представляет собой отдельный чтобы-документ. Таким образом, нам надо так определить набор фреймов, наши в правую часть страницы загружался -HTML-документ, (назовем этот файл sergtext.html), а в левый фрейм — файл, содержащий “автопортрет” Сергея Сегеева. Этот файл мы назовем sergport.html. Сначала напишем его текст.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТITLEЕ>Домашняя страница Сергея Сергеева.</TITLE>

<STYLE TYPE="text/css">

BODY { background-color: #BABAAO;

color: rgb(29,29,24);

} -->

</STYLE>

</HEAD>

<BODY>

<IMG
SRC="Images/sergport.gif" WIDTH="257"
HEIGHT="305" BORDER="0"
ALT="ABTOПOPTPET">

<HR> АВТОПОРТРЕТ СЕРГЕЯ СЕРГЕЕВА

</BODY>

</HTML>

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

Надо сказать, что НТМL-файлы, содержащие набор фреймов, существенно отличаются от обычных HTML-файлов. В частности, они не должны содержать тег <BODY> . Их основная часть определяется тегом <FRAMESET> . Все, что заключено между ним и его закрывающим тегом </FRAMESET> , является набором фреймов. Содержимое каждого фрейма задается с помощью тега <FRAME>. Его основным атрибутом является SRC=, значением которого является имя соответствующего .HTML-файла.

Кроме того, в первой строке файла, содержащего набор фреймов, необхидимо указывать тип Frameset, например, вот так:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">

Давайте напишем текст набора фреймов для нашего примера, а затем paссмотрим его подробнее. Итак, если страница с портретом называем ч sergport.html, а страница с текстом — sergtext.html, то текст основного документа будет следующим.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">

<HTML>

<HEAD>

<ТITLЕ>Домашняя страница Сергея CepreeBa</TITLE>

</HEAD>

<FRAMESET COLS="277,*" FRAMESPACING="0" FRAMEBORDER="0">

<FRAME NAME="portrait" SRC="sergport.html" SCROLLING="no" FRAMEBORDER="0" NORESIZE>

<FRAME NAME="text" SRC="sergtext.html" SCROLLING="auto" FRAMEBORDER="0" NORESIZE>

</FRAMESET>

</HTML>

Давайте внесем некоторые пояснения. Чтобы фреймы располагались, как столбцы таблицы (а не как ряды, Hanpимер, сверху и снизу), нужно в теге <FRAMESET> указать атрибут COLS= Его значением должно быть перечисление ширины каждого фрейма (через запятую). Например, если написать <FRAMESET COLS="25%,25%,50%">,то окно броузера будет разделено на три фрейма: левый шириной в четверть окна броузера, средний такой же ширины и правый шириной в половину окна броузера. В данном случае ширина каждого фрейма указана в про- центах. Можно также указывать ширину фрейма в пикселах. В приведенном выше коде мы определяем ширину левого фрейма в 277 пикселов чтобы туда уместился рисунок:

<FRAMESET COLS="277,*">

В этой записи звездочка означает, что для другого фрейма отведено все оставшееся место в окне броузера. Сколько его будет — зависит только отi ширины окна броузера на компьютере пользователя. (Если у пользователя разрешение 1600х1200 и окно броузера развернуто на весь экран, то у него ширина правого фрейма будет около 1320 пикселов, а если он сузил окно броузера до 300 пикселов, то на правый фрейм у него останется менее 15 пикселов.) В большинстве случаев левый фрейм шириной 277 пикселов будет все же занимать меньше половины окна броузера, а значит, у пользователя сложится правильное впечатление, что основная информация заключена в правом фрейме.

Далее, чтобы между фреймами на было видимой границы, следует установить значения атрибутов FRAMESPACING= (расстояние между фреймами) и FRAMEBORDER= (наличие рамки фреймов) равными нулю. В принципе, если установить значение атрибута FRAMEBORDER= равным 1 (кстати, для Netscape версии 3 было необходимо вместо значений 0 и 1 для атрибута RAMEBORDER= использовать значения Yes или No), то можно проконтролировать толщину рамки с помощью атрибута BORDER=, а также ее цвет с помощью атрибута BORDERCOLOR=.

Если надо расположить фреймы, как строки таблицы, то вместо атрибута COLS= следует использовать атрибут ROWS=. В остальном все остается точно так же, как ранее. В принципе, возможно использовать в одном теге <FRAMESET> оба атрибута: и COLS=, и ROWS=.

Но вернемся к приведенному выше коду. Между тегами <FRAMESET> и </FRAMESET> в нем находятся определения содержимого каждого из фрей-мов. Каждый фрейм определяется с помощью тега <FRAME>:

<FRAME NAME="portrait" SRC="sergport.html" =SCROLLING"nо" ' FRAMEBORDER="0" NORESIZE>

<FRAME NAME="text" SRC="sergtext.html" SCROLLING="auto" FRAMEBORDER="0" NORESIZE>

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

Атрибут SRC=, как уже говорилось выше, является самым главным атрибутом,

поскольку его значение указывает, какой, собственно говоря, файл следует в этот фрейм загрузить. Атрибут SCROLLING= управляет наличием полосы прокрутки в каждом фрейме. Если его значением является auto, то броузер сам определяет, отображать ли полосу прокрутки. Как правило, это самое удобное значение — если все содержимое фрейма помещается и видимую область, то полоса прокрутки не отображается, а если часть содержимого не видна, то полоса прокрутки отображается.

И, наконец, атрибут NORESIZE означает, что пользователь не может изменять ширину (или высоту) данного фрейма. Если этот атрибут не установлен, то при желании можно передвигать границу между фреймами помощью мыши.

Как видите, все достаточно просто. Нужно только не забывать определи нужное количество тегов <FRAME>. Впрочем, если их будет меньше, не указано в теге <FRAMESET> , то на месте “отсутствующего” фрейма отобразится просто белый прямоугольник.

Вложенные наборы фреймов

— Хорошо, — скажете вы, а как быть, если мы захотим, к примеру, oто- бразить заголовок страницы во всю ширину окна броузера, а уж под ним расположить левый и правый фреймы?

— Это весьма просто. Создадим отдельный НТМL-файл заголовка.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТITLЕ>Домашняя страница Сергея Сергеева. </TITLE>

<STYLE TYPE="text/css">

<!--

BODY { background-color: #BABAAO;

color: rgb(29,29,24); . } HI { text-align: center; }

-->

</STYLE> </HEAD>

<BODY>

<Н1>Домашняя страница Сергея Сергеева</Н1>

</BODY>

</HTML>

Назовем этот файл, например, serghdr. html. Далее удалим заголовок из файла sergtext.html. И теперь давайте немного подумаем. Чтобы расположить наш заголовок в верхнем фрейме, придется сначала определить набор горизонтальных фреймов с помощью атрибута ROWS= в теге <FRAMESET>:

<FRAMESET ROWS="80,*" FRAMESPACING="0" FRAMEBORDER="0">

Здесь мы определили высоту верхнего фрейма в 80 пикселов — вполне достаточно для заголовка. Теперь определим содержимое верхнего фрейма (загрузим туда наш только что созданный файл serghdr.html):

<FRAME SRC="serghdr.html" NAME="header" FRAMEBORDER="0" SCROLLING="no">

Теперь нужно определить содержимое нижнего фрейма. А что там должно находиться? А там должен находиться тот самый набор фреймов, который был определен в прошлом примере! К счастью, нам ничто не мешает в качестве содержимого одного из фреймов указывать тег <FRAMESET> — ведь каждый фрейм имеет те же “права”, что и отдельное окно броузера! Вот что у нас получится в целом.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">

<HTML>

<HEAD>

<ТITLE>Домашняя страница Сергея CepreeBa</TITLE>

</HEAD>

<FRAMESET ROWS="80,*" FRAMES РАСING="0" FRAMEBORDER="0">

<FRAME SRC="serghdr.html" NAME="header" SCROLLING="no">

<FRAMESET COLS="277,*" FRAMESPACING="0" FRAMEBORDER="0">

<FRAME NAME="portrait" SRC="sergport.html" SCROLLING="no" NORESIZE>

<FRAME NAME="text" SRC="sergtext2.html" SCROLLING="auto" NORESIZE>

</FRAMESET> </FRAMESET> </HTML>

Навигация между фреймами

А теперь давайте рассмотрим чуть более сложный пример. Попытаемся наконец, организовать полную навигацию по сайту гипотетической фирмы “Лентяй”, отдельные части которого мы создали в предыдущих главах. Здесь в правой части имеются гиперссылкп на различные разделы сайта, но при создании примера эти гиперссылю i не действовали. А ведь по крайней мере три из них могут действовать, поскольку три раздела: “Услуги”, “Цены” и “Книга отзывов” уже созданы!

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

Прежде всего, нам придется выделить в отдельные файлы заголовок и блок гиперссылок. Кроме того, чтобы пользоваться одинаковыми стилями г нескольких HTML-файлах сразу, мы не будем дублировать таблицу стилей в каждом из файлов, а тоже выделим ее в отдельный файл. Назовем и, его lent.css. Давайте вначале взглянем на его содержимое:

BODY { background-color: #D2FFFF;

color: #003737;
background-image: url("Images\grad2.jpg");
background-position: right; background-repeat: repeat-y;

} A:link,A:active,A:visited { color: #006A6A; }

A:hover { font-weight: bold; text-decoration: none;

}

.hdr { position: absolute; left: 50px; top: 10px; text-align: center; font-family: OdessaScriptFWF, fantasy;

font-size: 60px; font-weight: 900; width: 90%; height: 100px; letter-spacing: 0.05em; line-height: 100px; filter: shadow; border: 10px outset #003163; color: #3163CE;

} .rght { font-size: large;

}

.Ink { border-width: thick; border-style: ridged; margin: 10px; padding: 5px; border-color: #319CFF;

background-image: url("Images\backlnkl.jpg");

color: red; text-align: center; }

.Ink A:link, .Ink A:visited {

text-decoration: none; color: white;

} .Ink A:active ( text-decoration: none;

color: red; }

.1ft { font-size: meduim; }

.bigger { font-size: larger;

font-family: sans-serif; }

.logo

{ position: absolute;

left: 70; top: 120; z-index: -5;

}

Как видите, эта таблица стилей очень похожа на ту, однако в нее пришлось внести некоторые изменения. Поскольку все разделы будут теперь располагаться в отдельных фреймах, отпадает необходимость в позиционировании, поэтому для классов Ift и rght свойства position, left, top, width и height мы вообще не опре делили. Кроме того, изменена позиция (свойства left и top) логотипа, то есть класса logo. Для выделения красным цветом ссылки на текущий раз дел (то есть тот, который в данный момент просматривает пользователь) пришлось добавить псевдокласс .Ink Aactive.

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">

<HTML>

<HEAD>

<ТIТLЕ>Фирма "Лентяй"</ТIТLЕ>

</HEAD>

<FRAMESET ROWS="150," FRAMES РАСING="0" FRAMEBORDER="0">

<FRAME SRC="lenthdr.html" NAME="header" FRAMEBORDER="0" SCROLLING="no">

<FRAMESET COLS="*,200" FRAMESPACING="0" FRAMEBORDER="0">

<FRAME NAME="main" SRC=°"main.html" FRAMEBORDER="0" NORESIZE>

<FRAME NAME="link" SRC="lentlink.html" FRAMEBORDER="0" NORESIZE>

</FRAMESET> </FRAMESET>

</HTML>

Теперь создадим файл заголовка lenthdr.html. Собственно говоря, он будет очень коротким, поскольку в нем не должно быть ничего, кроме заголовка, написанного классом hdr, уже определенным в файле lent.css. Надо только не забыть подключить файл таблицы стилей с помощью тега <LINK>:

<LINK REL="stylesheet" HREF="lent.css"> Взглянем на текст этого файла целиком.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Фиpмa "ЛEHTЯЙ"</TITLE>

<LINK REL="stylesheet" HREF="lent.css"> </HEAD>

<BODY> <DIV CLASS="hdr">Фиpмa&nbsp;&laquo;ЛEHTЯЙ&raquo;</DIV>

</BODY>

</HTML>

Итак, посмотрим целиком на текст файла lentlink.html.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<title>Фирма "ЛEHTЯЙ"</title>

<LINK REL="stylesheet" HREF="lent.css"> </HEAD>

<BODY>

<DIV CLASS="rght"> <DIV CLASS="lnk">

<A HREF="main.html" target="niain">ycnyги</A></DIV>

<DIV CLASS="lnk">

<A HREF="prices .html" target="main">цены</A></DI

<DIV CLASS="lnk">

<A HREF="forml.html" tаrgеt="main">ФОРМА 3AKA3A</A></DIV>

<DIV CLASS="lnk">

<A HREF="history.html" target="main">История

<SPAN STYLE="letter-spacing: -3px; ">KOMПAHИЯ</SPAN></A></DIV>

<DIV CLASS="lnk"><A HREF="guestbook.html" target="main">KHИГA OT3ЫBOB</A></DIV>

</DIV>

</BODY>

</HTML>

Собственно говоря, на этом этапе можно уже открыть основной файл и броузере. Правда, чтобы гиперссылки работали, давайте напишем еще файлы prices.html и guestbook.html.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Фиpмa "ЛEHTЯЙ"</TITLE>

<LINK REL="stylesheet" HREF="lent.css">

<STYLE> BODY { background-image: none } </STYLE>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

var foodlist = new
Array(25, 60, 10, 14, 100, 24, 7, 144); var foodingr = new
Array<50, 26, 5, 28, 32, 11, 3, 96); function calclamp() {

document.forms[0].lamptotal.value= parseint(document.forms[0].lamp.value)*7;

calcall();

} function calcchist() {

document.forms[0].chisttotal.value= parseint(document.forms[0].chist.selectedlndex)*35;

calcall() ;

}

function calcfood() { document.forms[0].foodtotal.value=0; for (var i=0; i<8; i++)

( if (document.forms[0].food[i].selected) {

document.forms[0].foodtotal.value= parseint(document.forms[0].foodtotal.value)+parselnt(foodlist[i]);

if (document.forms[0].ingred.checked)

document.forms[0].foodtotal.value= parseint(document.forms[0].foodtotal.value)+parselnt(foodingr[i]);

} } calcall();

} f unction calccomp() {

document.forms[0].comptotal.value= parseint(document.forms[0].comp.selectedlndex)*101;

calcall() ;

function calcall() {

document.forms[0].total.value=
parseint(document.forms[0].lamptotal.value)+
parseint(document.forms[0].chisttotal.value)+
parseint(document.forms[0].foodtotal.value)+
parseint(document.forms[0].comptotal.value) ;

//-->

</SCRIPT>

</HEAD>

<BODY>

<DIV CLASS="lft">

<DIV CLASS="bigger">

Здecь вы можете не только увидеть наши цены, но и рассчитать стоимость будущего заказа !</DIV>

<BR>

<FORM>

<TABLE WIDTH="99%" CELLSPACING="0"> <TR>

<TH WIDTH="70%">Услуги</TH>

<TH WIDTH="15%" ALIGN="left">ЦЕHA</TH>

<TH WIDTH="15%">CTOИMOCTb</TH> </TR> <TR> <TD>

Количество вкручиваемых лампочек:

<INPUT
TYPE="text" NAME="lamp" VALUE="0"
SIZE="2" MAXLENGTH="2"
onChange="calclamp () "></TD>

<TD ALIGN="center">

<INPUT TYPE="text" NAME="lampprice" VALUE="7" SIZE="3" READONLY> p.</TD>

<TD ALIGN="right">

<INPUT TYPE="text" NAME="lamptotal" VALUE="0" SIZE="3" READONLY> p.</TD>

</TR> <TR>

<TD> Количество услуг по наведению чистоты:

<SELECT NAME="chist" onChange="calcchist()">

<OPTION VALUE="0">0

<OPTION VALUE="1">1

<OPTION VALUE="2">2

<OPTION VALUE="3">3 </SELECT> </TD>

<TD ALIGN="center">

<INPUT TYPE="text" NAME="chistprice" VALUE="35" SIZE="3" READONLY> p.</TD>

<TD ALIGN="right">

<INPUT TYPE="text" NAME="chisttotal" VALUE="0" SIZE="3" READONLY> p.</TD>

</TR> <ТR><ТD>Приготовление пищи:<ВR>

<SELECT NAME="food" SIZE="4" MULTIPLE onChange="calcfood() ">

<OPTION VALUE="25">Cyп <OPTION VALUE="60">Kypинные котлеты

<OPTION VALUE="10">Maкapoны

<OPTION VALUE="14">Koмпoт

<OPTION VALUE="100">ПЛOB

<OPTION VALUE="24">КАША

<OPTION VALUE ="7">Кофе

<OPTION VALUE="144">Caлaт </SELECT><BR>

<INPUT
TYPE="checkbox" NAME="ingred"
VALUE="ours"
onClick="calcfood()">Привезти
ингредиенты с собой

</TD>

<TD ALIGN="center">

<INPUT TYPE="text" NAME="foodprice" VALUE="OT 10" SIZE="4" READONLY> p.</TD>

<TD ALIGN="right">

<INPUT TYPE="text" NAME="foodtotal" VALUE="0" SIZE="3" READONLY> p.</TD>

</TR> <TR><TD STYLE="padding-bottom: 15px;"> Количество компьютерных услуг: <SELECT NAME="comp" onChange="calccomp () ">

<OPTION VALUE="0">0 <OPTION VALUE="1">1 <OPTION VALUE="2">2 </SELECT></TD>

<TD ALIGN="center" STYLE="padding-bottom: 15px;">

< INPUT TYPE="text" NAME="compprice" VALUE="101" SIZE="3" READONLY> p.</TD>

<TD STYLE="padding-bottom: 15px;" ALIGN="right">

<lNPUT TYPE="text" NAME="comptotal" VALUE="0" SIZE="3" READONLY> p.</TD>

</TR> <TR>

<TD COLSPAN”"2" ALIGN="right" STYLE="padding-top: 15px; border-top: double black; "><В>ИТОГО:</В></ТD>

<TD ALIGN="right" STYLE="padding-top: 15px; border-top: double black; ">

<INPUT TYPE="text" NAME="total" VALUE="0" SI'ZE="3" READONLY> p.</TD>

</TR>

</TABLE>

</FORM>

</DIV>

<IMG
CLASS="logo" SRC="Images/logo6.gif"
WIDTH="500" HEIGHT="346"
BORDER="0">

</BODY>

</HTML>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Baш отзыв</ТITLЕ>

<LINK REL="stylesheet" HREF="lent.css">

<STYLE> BODY { background-image: none } </STYLE>

</HEAD>

<BODY>

<DIV CLASS="lft"> <Н1>Ваш отзыв о наших услугах</Н1>

<DIV ALIGN="center">

<FORM ACTION="http://cgi.lentyay.corn/guest.cgi" METHOD="post">

<LABEL FOR="Name">Baшe имя:</LABEL>

<INPUT
TYPE="text" NAME="Name"
VALUE="AHOHИM" SIZE="30"><BR>
<LABEL FOR="Opinion">Bame
мнение:</LABEL>

<TEXTAREA COLS="30" ROWS="4" NAME="Opinion " STYLE="vertical-align: middle;"></TEXTAREA>

<BR><BR>

<INPUT TYPE="submit" VALUE="Отправить">

<INPUT TYPE="reset" VALUE="Очистить форму"> </FORM> </DIV>

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


8.2

8.2. Управление расположением элементов веб-страницы с помощью таблиц

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

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

Сначала определим стили будущей страницы — цвет фона и центрирование текста:

<STYLE> BODY { background-color: #FOE7F1;

} H2 { text-align: center;

} TD { font-family: MS Comic Sans, sans-serif;

text-align: center; } </STYLE>

Теперь можно задать параметры самой таблицы. При этом отступ от внутраннего края ячейки (CELLPADDING=) и расстояние между ячейками (CELLSPACING=) лучше задать равными нулю, чтобы ничто не отвлекало нас от задания минимальных размеров ячеек:

<TABLE WIDTH="99%" CELLSPACING="0" CELLPADDING="0">

Создание ячеек таблицы

Теперь нужно определить сами ячейки. Если посмотреть на рис. 8.4, то может показаться, что их меньше, чем на самом деле. В процессе опреде-ления ячеек бывает удобно временно установить в теге <TABLE> атрибут BORDER=. В этом случае все границы между ячейками будут видимы.

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

<TR><TD COLSPAN="5">

<IMG
SRC="Images/diafanol. gif" WIDTH="4"
HEIGHT="20" BORDER="0"
ALT=""></TD></TR>

Как видите, высота этой строки равна 20 пикселам. Пустые ячейки в осталь ных строках используются для задания ширины столбцов, например, так.

<TD><IMG SRC="Images/diafanol.gif" WIDTH="20" HEIGHT="3"

BORDER="0" ALT=""></TD>

Здесь помещен прозрачный рисунок, “растянутый” по горизонтали. Остальные “пустые” ячейки также заполнены прозрачными рисунками. размеры которых проставлены, исходя из того, что ширина каждого рисунка гиперссылки равна 120 пикселам, а ширина всех отступов — 20 пикселе и

Давайте окинем взглядом весь текст этой страницы.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.О Transitional//EN">

<HTML>

<HEAD>

<ТITLЕ>Электронная библиотека</ТIТLЕ>

<STYLE> BODY { background-color: #FOE7F1;

} H2 { text-align: center;

} TD { font-family: MS Comic Sans, sans-serif;

text-align: center; }

</STYLE>

</HEAD>

<BODY>

<TABLE WIDTH="99%" BORDER="0" CELLSPACING="0" CELLPADDING="0">

<TR><TD СOLSPAN="5">

<Н2>Электронная библиотека</Н1>

</ТD>

</ТR>

<TR>

<TD><IMG
SRC="Images/hudlit.gif" WIDTH="120"
HEIGHT="120" BORDER="0"
ALT="Xyдoжecтвeннaя">

<BR>Xyдoжecтвeннaя литература </TD>

<TD
COLSPAN="4"><IMG
SRC="Images/diafanol.gif" WIDTH="280"
HEIGHT="3" BORDER="0"
ALT=""></TD>

</TR>

<TR><TD COLSPAN="5">

<IMG
SRC="Images/diafanol.gif" WIDTH="4"
HEIGHT="20" BORDER="0"
ALT=""></TD></TR>

<TR><TD>

<IMG SRC="Images/diafanol.gif" WIDTH="120" HEIGHT="3"

BORDER="0" ALT=""></TD><TD>

<IMG
SRC="Images/diafanol.gif" WIDTH="20"
HEIGHT="3" BORDER="0"
ALT=""></TD><TD>

<IMG
SRC="Images/naulit.gif" WIDTH="120"
HEIGHT="120" BORDER="0"
ALT="Hayчнaя"><BR>Hayчнaя
литература</ТD><ТD>

<IМG
SRC="Images/diafanol.gif" WIDTH="20"
HEIGHT="3"BORDER="0"
ALT=""></TD><TD>

<IMG
SRC="Images/diafanol.gif" WIDTH="120"
HEIGHT="3" BORDER="0"
ALT=""></TD></TR>

<TR><TD COLSPAN="5">

<IMG
SRC="Images/diafanol.gif" WIDTH="4"
HEIGHT="20" BORDER="0"
ALT=""></TD></TR>

<TR><TD COLSPAN="4">

<IMG
SRC="Images/diafanol.gif" WIDTH="280"
HEIGHT="3" BORDER="0"
ALT=""></TD><TD>

<IMG
SRC="Images/detlit.gif" WIDTH="120"
HEIGHT="120" BORDER="0"
ALT=""><BR>Детская
литература</ТD></ТR>

</TABLE>

</HTML>

В этом примере не поставлены сами гиперссылки, т. е. теги <А>, поскольку ни самой библиотеки, ни ее разделов пока что не существует. Добавить их не составит труда.

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

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


9

9. Дополнительные возможности формирования веб-страниц

В предыдущих главах мы рассмотрели основные приемы создания динамических веб-страниц, основанные на применении языка разметки HTML, таблиц стилей CSS и языка сценариев JavaScript. Собственно говоря на этом можно было бы и завершить эту книгу. Девятая глава, которую вы сейчас читаете, является лишь небольшим дополнением к основное тексту. В ней мы коротко проиллюстрируем некоторые дополнительны. возможности, которые имеются при создании веб-страниц. Такими возможностями являются, в частности, использование элементов управления Internet Explorer и применение простейших сценариев, исполняющихся на сервере.

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

9.1. Пример использования элемента управления Tabular Data

Использование элементов управления Internet Explorer имеет свои преимущества и недостатки. Преимущества заключаются в существенном расширении возможностей веб-страницы, а недостатки — в возможности просмотра только в Internet Explorer. Но поскольку этим броузером пользуется очень большое число посетителей WWW, применение элементов управления заслуживает внимания.

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

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

Текстовая база данных

Для этого давайте создадим файл базы данных, в которой хранятся все сведения об имеющихся в библиотеке книгах. Для примера предположим, что у нас всего восемь книг. Файл базы данных будет представлять собой обычный текстовый файл (с расширением txt), в котором каждая строка является записью — данными об одной книге. Каждая запись состоит из нескольких полей: автор, название книги, размер файла и имя файла для загрузки. Чтобы не усложнять код, будем в этом месте просто ставить гиперссылку. Поля будем отделять друг от друга запятыми, например, так:

Толстой,Анна Каренина,305,<А HREF="anna.ziр">загрузить</А>

Как видите, заполнение базы данных вполне можно поручить любому человеку, умеющему использовать компьютер как пишущую машинку. (В принципе, можно избавить его и от необходимости писать страшную конструкцию <А HREF> .) В начале файла базы данных напишем заголовок каждого поля. Вот что у нас получится:

Author,Name,Size:INT, File Дюма,Три мушкетера,250

<A HREF="trim.zip">3arpyзить</A> Дюма,Десять лет спустя,198,<А HREF="deslet.zip"> загрузить </А> Дюма,Двадцать лет спустя,170,

<А HREF="dvlet.zip"> загрузить </А> Толстой/Война и мир,1045,

<А HREF="vojna.rar"> загрузить </А> Толстой,Анна Каренина,305,<А HREF="anna.zip"> загрузить </А> Достоевский,Идиот,560,

<А HREF="idiot.zip"> загрузить </А>

Достоевский,Преступление и наказание,710,

<А HREF="prest.rar"> загрузить </А>

Достоевский,Двойник,432,

<А HREF="doppel.zip"> загрузить </А>

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

INT

Теперь давайте создадим саму веб-страницу. Сначала, как обычно, напи-шем заголовок и определим стиль вывода на экран:

<ТIТLЕ>Электронная библиотека</ТIТLЕ>

<STYLE> BODY { background-color: #F4FFEF;

color: #182F1A;

font-family: sans-serif; font-size: 120%;

} </STYLE>

</HEAD>

<BODY>

<Н1>Художественная литература</Н1>

Элемент управления для работы с базой данных

Теперь, чтобы иметь возможность обращаться к базе данных, поместим на страницу элемент управления — он называется Tabular Data):

<OBJECT
ID="hudlit"
CLASSID="clsid:333C7BC4-460F-llDO-BC04-0080C7055A83"
BORDER="0" WIDTH="CT HEIGHT="0">
<PARAM NAME="DataURL"
VALUE="books.txt"> <PARAM
NAME="UseHeader" VALUE="True">
</OBJECT>

Может показаться, что это выглядит “страшно”, но не пугайтесь, на самом деле все очень просто. Давайте разберемся. Элемент управления помещается на страницу с помощью тега <OBJECT>. При этом атрибут 1D= — это, как обычно, уникальное имя объекта. Столь необъятно выглядящий атрибут CLASSID= является всего лишь идентификатором (проще говоря, номером ) соответствующей системной подпрограммы. Всякий раз, когда необходимо вставить элемент управления Tabular Data, приходится вводить этот идентификационный номер — clsid:333C7BC4-460F-11DO-BC04-0080C7055A83. У других элементов управления другие номера, такие же длинные.

В первом из тегов <PARAM> мы связываем элемент управления с файлом базы данных. Здесь предполагается, что этот файл называется books.txt.

Второй тег <PARAM> указывает, что в базе данных первая строка используется как заголовочная. Это необходимо, поскольку далее мы будем o6pа-щаться к полям через их заголовки.

Динамическое формирование таблицы

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

Чтобы связать таблицу с элементом управления, используем атрибут

DATASRС=:<TABLE DATASRC="#hudlit">

Обратите внимание на то, что мы указываем здесь не файл базы данных, а имя элемента управления, связанного с этим файлом. Теперь мы можем определить строку таблицы. В тех местах, куда нужно вставить значение кого-либо поля из базы данных, необходимо использовать атрибут DATAFLD=. Его удобно устанавливать в тегах <DIV> и <SPAN>:

<TR>

<TD><SPAN DATAFLD="Author"></SPAN>, &laquo;

<SPAN DATAFLD="Name"></SPAN>&raquo;,

<SPAN DATAFLD="Size"></SPAN>&nbsp; кбайт.

<SPAN DATAFLD="File" DATAFORMATAS="html">

</SPAN></TD>

</TR>

Посмотрите внимательно на этот код. Здесь определена одна строка таблицы, состоящая из одной ячейки (можно было сделать и по-другому, напримеp, значение каждого поля поместить в свою ячейку). В этой ячейке последовательно отображаются: значения первого поля (автор книги), за- пятая, открывающая кавычка, значение второго поля (название книги), закрывающая кавычка, запятая, значение третьего поля (размер файла), пробел, слово “кбайт”, точка и значение четвертого поля (гиперссылка для загрузки текста книги). Обратите внимание на то, что в последнем случае нам пришлось использовать атрибут DATAFORMATAS='html', чтобы указать, что в базе данных содержатся НТМL-тетта. Если бы мы забыли применить этот атрибут, то в окне броузера ссылка отобразилась бы в виде исходного кода.

Собственно говоря, нам осталось только поставить закрывающие теги:

</TABLE>

</BODY>

</HTML>

Всe остальное сделает элемент управления Tabular Data. Он “пройдется” по всем записям файла базы данных, и для каждой из них автоматически создаст новую строку таблицы.

Фильтрация таблицы

Теперь можно добавить возможность выбора автора из списка и затем ото- бражать на экране книги только выбранного автора. Если в библиотеке очень много книг, такая возможность будет совсем не лишней! Сначала создадим список выбора с помощью тега <SELECT>.

Выберите автора: <SELECT NAME="auth" onChange="auth ()">

<OPTION VALUE="">Bce

<OPTION VALUE="Дюма">Дюма

<OPTION VALUE="Достоевский">Достоевский

<OPTION VALUE="Толстой">Толстой </SELECT>

Поскольку при выборе какого-либо из пунктов списка содержимое акии броузера должно изменяться, применим обработчик событий onChange (напомним, что он реагирует на изменения значения). Пусть он вызывает еще не написанную функцию auth(), которая будет выводить на экран книги только выбранного автора. Для облегчения написания этой функпии мы продублировали названия пунктов списка в атрибуте VALUE= каждого из тегов <OPTION>.

Теперь напишем эту функцию. Это проще, чем может показаться. Дело в том, что у нашего элемента управления есть свойство Filter, значением кото-рого может являться строка типа название поля=строка, то есть сравнение одного из полей с заданной строкой. В данном случае это может быть, например: Auther=Дюма.

Поскольку имя автора у нас уже хранится как значение атрибута VALUE= , мы можем написать так:

hudlit.Filter="Author="+document.all.auth.value;

Кстати, в качестве значения атрибута VALUE= первого элемента списка (“Все”) мы не зря использовали пустую строку. Сравнение с ней в любом случае даст положительный результат, поэтому она как бы отменяет фильтр. Теперь остается только перерисовать изображения с помощью метода Reset:

hudlit.Reset () ; Вот и все1 Давайте теперь посмотрим, что у нас получилось.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Электронная библиотека</ТITLЕ>

<STYLE> BODY { background-color: #F4FFEF; color: #182F1A;

font-family: sans-serif;

font-size: 120%; } </STYLE>

<SCRIPT> function auth() { hudlit.Filter="Author="+document.all.auth.value ; hudlit.Reset () ; } </SCRIPT>

</HEAD>

<BODY>

<Н1>Художественная литература</Н1> Выберите автора:

<SELECT NAME="auth" onChange="auth()">

<OPTION VALUE="">Bce <OPTION VALUE="Дюма">Дюма

<OPTION VALUE="Достоевский">Достоевский

<OPTION VALUE="Толстой">Толстой </SELECT> <BR><BR>

<OBJECT ID = "hudlit" CLASSID = "clsid:333C7BC4-460F-llDO-BC04-0080C7055A83" BORDER="0" WIDTH="0" HEIGHT="0">

<PARAM NAME = "DataURL" VALUE = "books.txt">

<PARAM NAME = "UseHeader" VALUE = "True"> </OBJECT>

<TABLE DATASRC = "#hudlit"> <TR>

<TD><SPAN DATAFLD="Author"></SPAN>, &laquo;

<SPAN DATAFLD="Name"> </SPAN>&raquo;,

<SPAN DATAFLD="Size"></SPAN>&nbsp;кбайт.

<SPAN DATAFLD="File" DATAFORMATAS="html"></SPAN></TD>

</TR>

</TABLE>

</BODY>

</HTML>

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

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

Рис. 9.1. Страница, на которой используются данные из базы

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

Поскольку мы используем элемент управления Tabular Data, обе эти зада решаются очень просто. Чтобы пользователь мог сам ввести название ну ной книги, создадим для этого текстовое поле и кнопку Поиск рядом с ним

<INPUT TYPE="text" NAME="book" SIZE="15" MAXLENGTH="25">

<INPUT TYPE="button" NAME="search" VALUE="Поиск" onClick="bookname()">

Как видите, кнопке Поиск мы назначили обработчик событий onClick. Тепе; при нажатии этой кнопки будет выполняться еще не написанная функция booknameO, которая должна выбрать из “базы данных” только те записи, в которых присутствует введенное пользователем название книги. Скорее всего, это будет одна запись, если, конечно, в базе нет книг с одинаковыи названиями, как, например, “ Записки сумасшедшего” Гоголя и “Записки сумасшедшего” Толстого.

Собственно говоря, эта функция очень похожа на предыдущую — нам ведь всего лишь нужно применить свойство Filter, в условии которого сравнить значения поля Name (название книги) со строкой, введенной пользователем:

hudlit. Filter="Name="+document. all. book. value;

hudlit.Reset() ;

Правда, для наглядности хорошо бы при поиске введенной пользовате-лем книги вернуть список выбора автора в исходное состояние, иначе может возникнуть следующая ситуация. Допустим, пользователь сначала выбрал из списка одного автора (например, пункт Толстой) и увидел на экранe список имеющихся книг Толстого. Затем он решил поискать книгу под названием “Тихий Дон” (которой в нашей базе данных пока нет). Он вводит в строку поиска название книги и, естественно, не получает ничего в ответ .В этот момент он смотрит на экран и видит, что у него в списке авторов выбран Толстой. Тогда он начинает думать, что, наверное, компью- тер искал “Тихий Дон” Толстого, хотя на самом деле фильтр применялся ко всей базе. Пользователь начинает раздражаться и нервничать.

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

списка выбора:

document. all. auth. selectedlndex=0 ; Эту строку мы добавим в функцию booknameO. Аналогично можно посту-пить и при поиске книг одного автора - на всякий случай очищать поле ввода названия книги. Для этого добавим в функцию auth() следующую строку:

document.all.book.value="";

Сортировка таблицы

Теперь давайте осуществим сортировку списка книг. Добавим для начала две кнопки — для сортировки по алфавиту, соответственно, авторов и названий книг:

<INPUT TYPE="button"VALUE="Сортировать по автору" onClick="sort_auth()">

<INPUT TYPE="button"VALUE="Сортировать по названию" onClick="sort_name()"> Теперь напишем сами функции сортировки. Для этого нам подойдет чудес-ное свойство элементоуправления Tabular Data, которое называется SortColumn. В качестве его значения нужно указать поле, значения которого нужно сортировать. Для сортировки по фамилиям авторов в данном случае сле-дует указать поле Author, а для сортировки по названиям книг — поле Name. После этого нужно не забыть применить метод Reset(), чтобы заново “перерисовать” весь список:

function sort_auth() { hudlit.SortColumn="Author"; hudlit.Reset() ;

} . function sort_name() { hudlit.SortColumn="Name" ; hudlit.Reset();

Кстати, применение метода сортировки может избавить от необходимости заботиться о расположении записей в файле базы данных Например, в данном случае при поступлении нового архива с текстом книги можно просто добавлять запись о нем в конец файла. При загрузке файла можно сразу применить сортировку. Кстати, это можно сделать и с помощью тега <PARAM>, который должен быть внутри тега <OBJECT> элемента управле-ния Tabular Data:

<PARAM NAME="SortColumn" VALUE="Author">

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

Давайте посмотрим на текст получившейся страницы.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Электронная библиотека</TITLЕ>

<STYLE> BODY { background-color: #F4FFEF;

color: #182F1A; font-family: sans-serif; font-size: 120%;

} </STYLE> <SCRIPT LANGUAGE""JavaScript" TYPE="text/javascript">

function auth() { document.all.book.value="";

hudlit.Filter="Author="+document.all.auth.value;

hudlit.Reset () ;

} function bookname() {

document.all.auth.selectedlndex=0;

hudlit.Filter="Name="+document.all.book.value;

hudlit.Reset (); } function sort auth()

{ hudlit.SortColumn="Author";

hudlit.Reset () ;

}

function sort_name()

{ hudlit.SortColumn="Name";

hudlit.Reset() ;

//-->

</SCRIPT>

</HEAD>

<BODY>

<Н1>Художественная литература</Н1>

<INPUT TYPE="button" VALUE="Сортировать по автору" onClick="sort_auth()">

<INPUT TYPE="button" VALUE="Сортировать по названию" onClick="sort_name()">

<BR><BR>

Выберите автора:

<SELECT NAME="auth" onChange="auth ()">

<OPTION VALUE="">Bce

<OPTION VALUE="Дюма">Дюма

<OPTION VALUE="Достоевский">Тостоевский

<OPTION VALUE ="Толстой">Толстой ;</SELECT>

<BR><BR> Или введите название книги:

<INPUT TYPE="text" NAME="book" SIZE="15" MAXLENGTH="25">

<INPUT TYPE="button" NAME="search" VALUE="Поиск" onClick="bookname()">

<BR><BR>

<OBJECT
ID="hudlit"
CLASSID="clsid:333C7BC4-460F-11DO-BC04-0080C7055A83"
B0RDER="0" ,WIDTH="0"
HEIGHT="0">

<PARAM NAME="DataURL" VALUE="books.txt">

<PARAM NAME="UseHeader" VALUE="True"> </OBJECT>

<TABLE DATASRC="#hudlit"> <TR>

<TD><SPAN DATAFLD="Author"></SPAN>, &laquo;

<SPAN DATAFLD="Name"></SPAN>&raquo;,

<SPAN DATAFLD="Size"> </SPAN>Snbsp;кбайт.

<SPAN DATAFLD="File" DATAFORMATAS="html"> </SPAN></TD>

</TR> </TABLE>

</BODY>

</HTML>

Результат показан на рис. 9.2. Конечно, это очень простой пример, который хочется еще улучшить. Например, перед поиском введенного пользователем названии книги хорошо бы сначала удалить лишние пробелы и кавычки, а если введенное название не найдено, то вывести сообщение oб этом. Можно использовать файл базы данных для построения нескольких различных страниц и т. д. Однако приведенный пример уже дает некоторое представление о возможностях элемента Tabular Data. Читателям, заинтересовавшимся использованием элементов управления в Internet Explorer, можно рекомендовать обратиться к специальной литературе по этой теме.

Рис. 9.2. Соративовка данных


9.2

9.2. Пример простейшего серверного сценария

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

Помните, когда мы создавали страницу гипотетической фирмы “Лентяй”, в ней был раздел “Книга отзывов”? Там пользователю предлагалось ввести свое имя в одно текстовое поле (с именем Name), а свое мнение — в другое (многострочное) текстовое поле (с именем Opinion). Затем, после нажатия кпопки Отправить заполненная форма отправлялась на сервер. Но что с ней происходит там?

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

Сценарий, исполняемый на сервере, может быть написан на различных языках программирования и использовать различные технологии. Напримеp, он может использовать технологию ASP (Active Server Pages) или специальную серверную редакцию языка JavaScript. Однако чаще всего такие сценарии пишутся на языке Perl (и используют технологию CGI — Common Gateway Interface). Мы сейчас не будем рассказывать об этом подробно, а просто проиллюстрируем, каким может быть простейший Perl- сценарий. Для облегчения восприятия давайте сначала напишем его построчно, а затем приведем полный текст.

Итак, в первой строке мы должны указать местоположение интерпретатоpa языка Perl на сервере. Его можно узнать у администратора сервера. Если сервер работает под управлением Windows NT, а не UNIX или Linux, эта строка будет проигнорирована. Обычно она выглядит так:

#! /usr/bin/perl Теперь, чтобы мы могли легко считывать данные HТМL-формы, надо написать еще одну строку:

require "cgi-lib.pl";

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

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

print "Content-type: text/html\n\n";

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

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

И последний совет: чтобы научиться свободно обращаться с HTML/CSS JavaScript, как можно больше экспериментируйте самостоятельно! Начинать можно с изменений и “улучшений” приведенных в книге примеров однако затем попробуйте создавать страницы самостоятельно “с нуля” или “ почти с нуля”. А если вы увидите в WWW какую-либо интересную и кра-сивую страницу, обязательно посмотрите на ее код, вникните в то, как она сделана. Такой опыт тоже очень полезен.

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