Содержимое раздела:

Web дизайн\Учебник по HTML

Глава 19. Dynamic HTML

Как вы думаете, что такое Dynamic HTML? Наверное, язык такой? А может быть, какой-то особый стиль написания страниц? Динамичный такой, напористый... Все гораздо проще. Когда на одной странице встречаются JavaScript, CSS и DOM, это часто называется Dynamic HTML. Эти документы предназначены для интерактивного взаимодействия с пользователями, включающего в себя некоторые спецэффекты, помогающие представлять информацию более ярко и информативно.
Вид DHTML может меняться от браузера к браузеру, и это вполне понятно. Даже такие гиганты, как Netscape и Microsoft, не хотят прийти к общему соглашению. В этой главе мы основное внимание уделим рассмотрению тех элементов, которые присутствуют в браузерах обоих производителей, обратим особое внимание на совместное использование JavaScript и таблиц стилей. Мы попытаемся создать, автоматически изменяющиеся страницы. Итак, разделы этой главы:

  • что такое Dynamic HTML, каковы преимущества его использования;
  • «величайшие хиты» Dynamic HTML: изменение изображения при наведении на него мыши;
  • слои: обзор возможностей, общие понятия, программирование;
  • работа с таблицами стилей: программирование классов и стилей.

Знакомьтесь: Динамический HTML

Давайте начнем разговор о Dynamic HTML с определения того, чем он не является. Dynamic HTML не является официальным стандартом. HTML превратился в XHTML и стал стандартом. CSS — стандарт с момента рождения. То же самое касается объектной модели документов (DOM). Но Dynamic HTML — это нечто большее, чем коммерческий термин. Большее, чем неофициальное название какой-нибудь спецификации, подразумевающей использование скриптов и DOM для I программирования каких-нибудь визуальных трюков. Dynamic HTML в некоторых случаях означает, что вы используете скрипты для изменения таблиц стилей В некоторых случаях означает, что вы включили в свой проект использование так называемых «слоев» — технологии, позволяющей накладывать разные части документа друг на друга и даже скрывать их.

Вы уже знакомы с небольшими примерами Dynamic HTML из главы 18, когда шел разговор о возможном доступе к массиву images и открытии и перезаписи объекта document. Мы расширим эти примеры в этой главе, узнаем кое-какие новые при емы. Для начала дополним понятие Dynamic HTML, пересмотрев заново объектную модель документов (DOM) и некоторые другие важные технологии.

ПРИМЕЧАНИЕ

В недавнем прошлом Dynamic HTML означал нечто другое. Netscape, к примеру, подразумевал под этим термином технологию скачиваемых шрифтов, которая была совершенно по-другому реализована у Microsoft и привела к их несовместимости. Microsoft же называла DHTML некоторые эффекты фильтрации, реализованные в браузерах этой фирмы. В данной главе я склонен подразумевать под этим понятием аспекты, связанные с CSS и CSSP (позиционирование CSS). Несколько другие аспекты отражены в специальных изданиях, посвященных непосредственно DHTML.

Вернемся к DOM

Тот факт, что объектная модель документов только недавно стала стандартом, действительно важен. Консорциум W3C принял в качестве рабочей версии для утверждения новой спецификации DOM уровня 3. Новейшие веб-браузеры (Internet Explorer 6.x и Netscape 6.x) имеют поддержку DOM-2, что тоже очень неплохо. Это означает, что IE и Netscape все-таки смогли сблизиться и стали более совместимыми, чем были раньше.

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

Несмотря на то что базовые объекты, которые вам встретились в главе 18, всегда были основополагающими и неизменными, к моменту появления браузеров поколения 4.0 возникло огромное множество дополнительных. В Internet Explorer почти все элементы страницы были превращены Microsoft в объекты, а значит, появилась возможность использования их в скриптах. Кроме того, документы, загруженные в Internet Explorer, получили возможность изменяться без перезагрузки, элементы можно было изменить «на лету». Netscape 4.x такого не умеет, хотя 6-я версия уже умеет, да и вообще, предлагает более полную реализацию теперь уже стандартизованной модели.

О совместимости браузеров

Эти совершенно разные подходы в конечном итоге затормозили процесс внедрения технологии DHTML, не говоря уж о том, что реализация отдельных ее составляющих — JavaScript, CSS — оказалась крайне несбалансированной. Какой вывод отсюда следует? DHTML внедрен, стандарты отдельных частей согласованы, поэтому имеет смысл использовать именно его, даже если возникает желание использовать на веб-странице какой-то другой формат. Пользователь не сможет оценить
ваш шедевр, потому что не увидит ничего вообще. Я считаю, что нужно с виртуальных трибун своих веб-сайтов пропагандировать новейшие браузеры, ставить ссылки на те места, откуда их можно скачать. По крайней мере, если ваш сайт хоть как-то связан с информационными технологиями. Конечно, если информационное пространство, созданное вами, посвящено японскому искусству, то пропаганда каких-то браузеров будет неуместна. IE 5.5 и 6, Netscape 6 более или менее стан дартизованы, приемы DHTML в применении к ним оказываются в основном кросс-платформенными.

В этой главе мы не будем снова вспоминать времена 4-го поколения двух извест ных браузеров, поскольку уже существуют определенные стандарты W3C и надо стараться придерживаться их. Если же вам придется когда-нибудь писать сайт для какого-то конкретного нестандартного браузера, используйте переадресацию. Скорее всего, для такого браузера соответствующая страница будет представлять со бой просто урезанную исходную. В ней не будет JavaScript, возможно, не будет фреймов. Я еще помню те годы, когда на очень многих сайтах в углу висела маленькая табличка, предупреждающая о том, что лучшая программа просмотра для этой странички — это, например, Netscape. Можно поступить так же, хотя смотрится это несколько архаично в наше время, когда все только тем и занимаются, что борются за совместимость.

Чтобы узнать больше о том, что может, а чего не может в плане использования DHTML тот или иной браузер, лучше всего сходить на сайт его производителя. Например, на сайте Netscape можно узнать многое по вопросам, связанным с DOM, DHTML и Netscape 6 (http://developer.netscape.com/tech/dom/). О взаимоотношениях Netscape 4.x и DHTML можно узнать на http://developer.netscape.com/tech/ dynhtml/index.html. О Microsoft, HTML и DHTML читайте на сайте
http://msdn.mi crosoft.com/libra ry/default.asp?url=
/workshop/author/dhtml/dhtml_node_entry.asp.

ПРИМЕЧАНИЕ

Подобная манера Microsoft составлять такие URL (как показано выше) — ярчайший пример того, как не следует делать, если вы хотите, чтобы посетители к вам стремились. Видимо, компании Microsoft, несмотря ни на что, не грозит пострадать от недостатка посетителей ее сайта, только этим можно объяснить такое пренебрежительное отношение к собственным адресам. Если есть возможность, старайтесь избегать косвенных URL, делайте ссылки проще.

CSS и CSSP

Начиная с версии 4.0 и Netscape, и Internet Explorer имеют поддержку стандарта каскадных таблиц стилей и их программируемых элементов. Можно сказать, что CSS — это основная составляющая Dynamic HTML.

Кроме стандарта CSS, о котором мы уже вели долгий разговор в главе 10, есть еще одна технология под названием CSSP (CSS Positioning), смысл которой состоит в том, чтобы не только задавать стиль элементов HTML, но и точно определять их местоположение, позиционирование на странице. В частности, можно накладывать одни элементы на другие, прятать их друг за дружкой. Но самое интересное заключается в том, что и IE 6, и Netscape 6 знают о том, что элементы CSSP — программируемые. Их можно изменять с помощью скриптов, и сейчас мы узнаем, каким образом это делается.

Просто наводим указатель мыши на элемент, и...

...Он изменяется. Это очень популярная шутка, которую позволяет реализовать DHTML. И графику, и свойства текстовых сообщений можно менять по событию, которое называется onmouseover, то есть «наведение указателя мыши». Щелкать на элементе не надо — все произойдет само. Скрипты, обрабатывающие onmouseover, создаются очень просто (что, несомненно, добавляет им популярности), а выглядят эффектно.

Хотя этот прием, основанный на CSS (использующий псевдоклассы типа a.hover), будет работать и в Netscape 4, но, если его переписать под DOM, про этот браузер можете забыть. Только IE 4 и выше или Netscape 6 и выше. Если с помощью эффекта наведения мыши вы хотите передать какую-то важную информацию-, то следует позаботиться о пользователях более старых браузеров.

Наведение указателя мыши на изображение

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

Листинг 19.1. Наведение указателя мыши на изображение

<!DOCTYPE html PUBLIC "\//W3C//DTD XHTML
1.0 Transitional//EN"
"http://www.w3.org/TR/xhtmll/DTD/xhtmll-transitional.dtd">
<html xml ns="http://www.w3.org/1999/xhtml">
<head>
<title> Смена изображения при наведении мыши
</title>
</head>
<script type="text/javascri(}t"> <!_.
. function changelmage() {
document, images.
m|y Image. src="second. jpg"; }
function changeBackO {
document.i mages.myImage.src="fi rst.jpg":
// --> </script>
<body>
<р>Наведение указателя мыши
на изображениеы изменяет его...</р>
<img src="first.jpg" id="mylmage"
onmouseover="changelmage()" onmouseout=
"changeback()" />
</body>
</html>

Когда пользователь помещает указатель мыши на изображение, файл first.jpg заменяется на second.jpg. При сдвиге указателя в какую-нибудь сторону старое изображение возвращается на место. Эти состояния показаны на рис. 19.1, а и 19.1, б.

Рис. 19.1, а. Страница до наведения указателя мыши на картинку

Рис. 19.1, б. Страница после наведения указателя мыши на картинку

ПРИМЕЧАНИЕ

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

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

function changelmage()
{
document .images . images01 . src=" second . jpg" :
}

В этом примере изображению было присвоено имя с помощью атрибута i d=" i mage01 " . Атрибут — новый для элемента <img>. Он позволяет сослаться на картинку по имени, указанному в этой объектной ссылке. Это удобно, но так делать не обязательно. Как вы помните, images — это массив. Значит, к его элементам можно получить доступ по их индексам. Так, например, встречаются такие участки кода:

 function changelmageO 
{
document. images [0].src=" second. jpg":
}

Вы получите тот же результат, так как imageOl и image[0] представляют собой одну и ту же ссылку.

Дистанционное изменение изображений по наведению указателя мыши

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

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

ПРИМЕЧАНИЕ

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

Листинг 19.2 содержит код такой страницы.

Листинг 19.2. Удаленное управление сменой изображений

<!DOCTYPE html PUBLIC "V/W3C//DTD XHTML
1.0 Transitional/7EN" "http://www.w3.org/TR/xhtmll/
DTD/xhtmll-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<titlе>Демонстрация динамических изображений<titlе>
</head>
<style> a. h1 {font-family: Ariel. Helvetica} </style>
<script type="text/javascript">
function changelmage (indexNum)
{
if (indexNum==l) document.images.
image01.src="main.jpg";
if (indexNum==2) document.images.
image01.src="maple.jpg":
function changelmage (indexNum) {
document.images.image01.src="logo jpg";
)
// -->
</script>
<body>
<h1>Пёрёчень домов, выставляемых
на продажу</h1> - , .

<table border="0" width="600" cellpadding="10">
<tr>
<td width="380">
<p><a href="1980.html" onmouseover=
"change!mage(l)" onmouseout="changeBack()">
1980 Главная ул.</а></р>
<р>Этот прекрасный загородный дом расположен
в саном сердце старого города. Это придает ему
особую прелесть. </р>
<а href="1730maple.html" onmouseover=
"changelmage(2)" onmouseout="changeBack()">
1730 Кленовая ул.</а></р>
<р>Рядом с этим домом расположены не
только хорошие школы и парк с раскидистыми кленами,
но и прекрасные утоптанные дорожки. </р>
</td>
<td width="200">
<div align="center">
<img src="logo. jpg" id="image01" />
</td>
</tr>
</table>
</body>
</html>

Этот скрипт очень сильно напоминает тот, что представлен в листинге 19.1, особенно сами функции, выполняющие всю работу по смене изображений. Единственное отличие состоит в наборе условных выражений (if), с помощью которых определяется, какие файлы должны быть загружены, в зависимости от гиперссылки. Каждая отдельная ссылка передает собственный индекс, благодаря чему и представляется возможным выстроить последовательность загружаемых изображений. На рисунке 19.2 показан скрипт в действии.



Рис. 19.2. Указатель мыши наведен на ссылку (сверху), и изображение, как видите, поменялось (снизу)

Предварительная загрузка графики

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

Листинг 19.3. Предварительная загрузка изображений для обработки события mouseover

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML
1.0 Transitional//EN"
"http://www.w3.org/TR/xhtmll/DTD/xhtmll-transitional.dtd">
<titml xmlns="http://www.w3.org/1999/xhtml">
<head>
</title>Предварительная загрузка графики</title>
</head>
<script type="text/javascript">
function loadImages () {
image01 = new Image(): image01. src =
"first.jpg"; image02 = new Image(); image02.src =
"second.jpg":
function changelmage () {
document.images.myImage.src=i mage02.src: }
function changeBack () {
document.images.myImage.src=image01.src:
// --> </script> <body>
<script type="text/javascript">
<!--
loadlmages();
// -->
</script>
<р>Указатель мыши, наведенный на изображение,
изменяет его:</р>
<img src="first.jpg" id="mylmage" onmouseover=
"changelmage()" onmouseout="changeBack()"
</body> </html>

Главное, что отличает этот скрипт от других, — это новая функция loadlmages() которая вызывается из тела скрипта, загружая тем самым графику в кэш браузера Делается это путем создания нового объекта Image (команда new Image()) и сопо ставления ему определенного файла (атрибут src). Объект Image является встро енным в JavaScript, поэтому отдельно описывать его в программе не нужно. Вновь созданные объекты могут использоваться в функциях changelmage() и changeBack() Интересно, что при их вызове изображения уже оказываются загруженными компьютер пользователя, ему не приходится долго ждать их выкачивания с сервера.

CSSP и слои

Наиболее кросс-платформенной частью всей технологии DHTML является CS Positioning - расширение стандарта CSS, позволяющее очень точно указыва размещение элементов на странице. Благодаря своей совместимости практически со всеми стандартными браузерами, страницы, на которых используется CSSP будут выглядеть примерно одинаково и в IE, и в Netscape 4, и в Netscape 6.

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

Могу сказать, что наиболее запутанной оказывается решение вопроса в Netscape 4, где можно нормально динамически изменять страницы, только если они созданы с использованием <lауег> и <ilауег> — двух элементов, придуманных Netscape. Они позволяют располагать одни части страницы над другими, устанавливать види мость слоев, динамически скрывать и показывать содержимое.

К сожалению, элементы <lауег> тоже не входят в установленные консорциумом W3C стандарты. После того как компания Netscape осознала этот факт, они были убраны. Мы кратко рассмотрим их, но я рекомендую пользоваться для позиционирования элементов специально для этого предназначенным стандартом CSSP. Последний будет работать в любом из трех браузеров.

Основы CSSP

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

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

К CSSP довольно легко можно привыкнуть, если вы уже знакомы с обычным CSS. Это, в общем-то, почти то же самое. В большинстве случаев вы просто будете создавать новый класс, указывая конкретное расположение элемента. После этого можно либо добавить атрибут cl ass в элемент, либо использовать <span> или <div>, сопоставив один и тот же класс множеству элементов HTML. Для начала неплохо бы узнать о некоторых полезных свойствах CSS, встречающихся при позиционировании. Они показаны в табл. 19.1.

Таблица 19.1. Свойства CSSP

Свойство Возможные значения Пример
position absolute, relative, static position: absolute
left Числа и ед. измерения left: 100рх
top Числа и ед. измерения top:50px
width Числа и ед. измерения width:250px
height Числа и ед. измерения height:5in
clip rect (вершина, правый угол, низ, левый угол) clip: rect(100px, 50px, 50px, 100рх)

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

ПРИМЕЧАНИЕ

Если вы укажете position: static, то элемент будет вести себя так, будто нет над ним никакого CSSP.

Если какое-то из этих свойств и может вызвать недоумение, так это свойство clip, использующееся для того, чтобы сделать видимой только какую-то часть страницы. Оно напоминает прием из графических редакторов под названием «обрезание изображения» (рис. 19.3). Не очень понятно пока что, зачем это нужно, но пример кода я приведу:

 .story_text {
position: absolute:
left: 25px;
top:80px:
width: 210px:
Clip: rect(10px', 200px. 500px. 10рх):
 }

СОВЕТ

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

Рис. 19.3. Обрезанный по краям текст выглядит так, будто он был обработан в графическом редакторе

Чтобы увидеть, как все это складывается и составляет единый стиль, рассмотрим такой пример.

Листинг 19.4. Позиционирование заголовка и текста с помощью CSSP

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML
1.0 Transitional//EN"
"http://www.w3.org/TR/xhtmll/
DTD/xhtmll-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<titlе>Небольшой пример CSSP</title>
</head>

<style type="text/css">
.headlinel {
position: absolute; left: 25px: top:
20px; width: 200px: height: 50px:

.story_text {
position: absolute: left: 25ox:
CSSP и слои
top: 80px: width: 210px;
</style>
<body>
<h1 class="headlinel">Пенье без музыки</h1>
<div class="story_text">
<р>Когда ты вспомнишь обо мне в краю
чужом -- хоть эта фраза всего лишь вымысел,
а не пророчество, о чем для глаза, вооруженного
слезой, не может быть и речи: даты из омута такой
лесой не вытащишь.</р>
<pxstrong>H. Бродский. 1970</strong</p> </body>
</html>

Рис. 19.4. Вот каким стройным получилось оформление, благодаря CSSP

Как видно на рис. 19.4, CSSP дает уникальную возможность управления располo жением элементов на странице. Единицы измерения, используемые в листинге, -это пикселы; пожалуй, наиболее универсальный способ обозначать расстояния в ок не браузера. Обратите внимание, что вид шрифтов может очень сильно повлиять на то, как в итоге будет выглядеть вся страница. Возможно, вы захотите объеди нить два подхода: CSSP и обычный.

Перекрытие элементов. Z-индекс

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

story_text {
 position: absolute:
left: 25px:
top: 25px;
width: 210px:
 }

На рисунке 19.5 показано, как это выглядит.

Рис. 19.5. Использование CSSP для создания перекрывающихся элементов

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

Листинг 19.5. Перекрытие элементов с помощью CSSP

<!DOCTYPE html PUBLIC "V/W3C//DTD XHTML 
1.0 Transitional//EN"
"http://www.w3.org/TR/xhtmll/DTD
/xhtmll-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<titlе>Наложение текста на изображение</titlе>
</head>
<style type="text/css">
.image
position: absolute: left: 25px: top:
20px: width: ЗООрх: height: 225px: z-index: 0:
.cutline
position: absolute: left: 125px: top:

200px: width: 210px: z-index: 1: font-face:
courier: font-weight: bold: color: white:
</style>
<body>
<img src="house.jpg" class="image" />
<p class="cutline">12:04: Домик моей любимой бабушки</р>
</body>
</html>

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

Хотите указать, какой элемент будет «сверху», а какой — снизу? По умолчанию : позже определен элемент, тем «выше» он оказывается в этом бутерброде, Однако существует и специальное свойство z-index, с помощью которого можно изменить этот порядок. Чем больше его значение, тем ближе к верхнему слою ходится элемент. (Однако имейте в виду, что z - i ndex распознается в Netscape 6 и IE, но не в Netscape 4, где вообще для таких вещей используются элементы <lауег>.)

Легким движением руки текст, наложенный на рисунок, из предыдущего примера ревращается в рисунок, наложенный на текст. Конечно, мы поменяем цвет и раз мер этого текста, но все равно непонятно, для чего предназначен этот новый вариант примера.


Рис. 19.6. Текст, наложенный на изображение

Рис. 19.7. Изменение атрибута z-index привело к изменению порядка слоев

 <style type="text/css">
.image {
position: absolute: left: 25px: top: 20px: width: ЗООрх;
CSSP и слои 349
height: 225px; Z-index: 1;
.outline {
position: absolute; left: 125px: top: 200px; width:
210px: z-index: 0: font-face: courier; font-weight: bold; font-size:
36pt: color: black: }
</style>

А всего лишь поменяли местами значения параметра z-index

На рисунке 19.7 показано, как это смотрится в браузере.

Вложенное позиционирование элементов

До сих пор мы имели дело с элементами и группами элементов, являющимися совершенно независимыми друг от друга. Одно начиналось только после окончания другого. Но что произойдет, если вложить свойства позиционирования друг в друга? При использовании абсолютного позиционирования (position; absolute) расположение каждого последующего элемента рассчитывается относительно «родительского». В наших последних примерах таким родительским элементом являлся <body>.

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

Посмотрим, что будет с листингом 19.4, если мы изменим его и вложим один из элементов в другой. Результат показан в листинге 19.6. (Из соображений экономии ме ста, я вырезал текст стихотворения, который был приведен целиком в листинге 19.4.)

Листинг 19.6. Вложенные элементы CSSP

<!DOCTYPE html PUBLIC "V/W3C//DTD XHTML 
1.0 Transitional//EN"
"http://www.w3.org/TR/xhtmll/DTD/
xhtmll-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>npHMep вложения элементов
CSSP</title>
</head>
<style type="text/css">
.headlinel {
position: absolute: left: 25px; top:
20px; width: 200px: height: 50px;
)
.story_text { position: absolute: left: 25px: top: 80px: width: 210px:
</style>
<body>
<div class="headlinel"> <h1>Пенье без музыки</h1>
<div class="story_text"> <p><strong>
TeKCT Текст Текст</р>
</div>
</body>
</html>

Классы были заключены вдва контейнера <di v>, первый из которых содержит вто рой. Результирующая страница (рис. 19.8) немного отличается от своего предыдущего варианта.

Рис. 19.8. Поскольку второй элемент <div> вложен в первый, то его координатная сетка
сдвинулась налево и вниз

Относительное позиционирование

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

Относительное позиционирование (position: relative) означает, что данная груп-па элементов по каким-то причинам должна отсчитывать свою координатную сет ку от того места, где она бы располагалась в отсутствие указанного стиля. То есть относительность в общем случае имеется в виду по отношению ко всему остально му документу. При этом обычно имеется необходимость указать еще какие-ни-будь параметры группы, например ширину прямоугольника или z-index.

Например, взяв за основу листинг 19.6 и поменяв в нем вторую строку определения класса:

.story_text {
position: relative: top: 5px; }

мы изменим абсолютное позиционирование на относительное.

Поскольку в данном случае story_text является порожденным классом по отношению к headlinel (то, о чем только что говорилось в предыдущем параграфе), то текст будет по-прежнему соотносить свои координаты с заголовком, то есть в итоге ничего не изменится. Так что определение могло быть и проще: можно было лишь указать, что story_text должен быть сдвинут вниз на 5 пикселов относительно того, где он должен был бы быть.

ПРИМЕЧАНИЕ

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

Динамическое позиционирование и слои

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

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

Существует особый случай, когда слой становится более значимым словом. Я имею в виду Netscape 4.x и его горячую любовь к элементу <lауег> (название которого дослов-з переводится как «слой»). Я оговорюсь, что Netscape 6 тоже имеет поддержку <lауег>, но сделано это лишь из соображений совместимости версий. Использовать этот эле мент крайней не рекомендуется. Поскольку этот элемент во всех смыслах устарел.

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

Слои CSSP

При создании слоев на основе технологии CSSP вы обнаружите, что процесс очень похож на то, что было продемонстрировано ранее в этом параграфе. Итак, мы создаем слой. Для этого понадобится селектор идентификаторов (#) в определениях стилей (<style>), а не классов, потому что у каждого слоя должен быть собственный id.

Все это вместе выглядит следующим образом:

 <div id="имя_слоя">

В листинге 19.7 следует обратить внимание на два слоя, определенных с помощью
селектора id и элемента <div>.

Листинг 19.7. Создание слоев CSSP

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Слои CSSP</title>*
<style type="text/css"> #mydivl {
position: absolute: top: 50px; left: 50px:
height: ЗООрх; width: SOOpx: }
#mydiv2 {
position: absolute; top: 350px; left: 50px;

height: ЗООрх: width: 5OOpx;
}
</style>
</head>
<body>
<!-- Начинается первый слой -->
<div id="mydivl">
<img src="1980main.jpg" />
<р>Этот прекрасный загородный дом расположен
в самом сердце старого города. Это придает ему
особую прелесть.</р>
<!-- Кончился первый слой -->
<!-- Начинается второй слой --
<div id="mydiv2">
<img src="1730maple.jpg" />

<p>Рядом с этим домом расположены не
только хорошие школы и парк с раскидистыми кленами,
но и прекрасные утоптанные дорожки

<!-- Кончился второй слой -->
</body>
</html>

В результате получаются два четко определенных элемента <div>, которые могут использоваться
для изменения позиционирования и даже видимости элементов. Как именно это делается, вы увидите в следующих параграфах. В качестве маленького примера могу привести такой листинг. Все, что нужно
сделать по сравнению с предыдущим кодом, — это поменять местами селекторы id в определениях style:

 <style type="text/css">
 #mydiv2 {
position: absolute: top: 50px:
left 50px; height: З00рх: wifth: 500px:
)
#mydivl {
position: absolute: top: 350px: left: 50px: height:
ЗООрх: wifth: SOOpx:
)
</style>

Если вы проделаете это и откроете страницу в браузере, то увидите, что слои поме нялись местами. Теперь содержимое второго контейнера <div> оказалось сверху, а первого — снизу. *

Динамическое позиционирование

Теперь вы уже знаете, как размещать элементы на странице. Следующий шаг будет состоять в добавлении JavaScript, благодаря чему появится настоящая динамичность. (В противном случае такую страницу тяжело называть написанной с применением DHTML.) Вот хотя бы такой простой пример. Вы берете какой-нибудь объект, опре деляете его размещение на странице, пишете небольшой скрипт, который будет изменять динамически это размещение. Объект получится как бы анимированным.
Что ж, давайте попробуем. Проиллюстрирую свои слова листингом 19.8. (Между прочим, такой скрипт будет работать только в Internet Explorer версий 4 и 5.)

Листинг 19.8. Перемещение объекта по странице

 <!DOCTYPE html PUBLIC "\//W3C//DTD XHTML l.O 
Transitional//EN" •tp://www. w3.org/TR/xhtmll/
DTD/xhtmll -transitional .dtd">
html xmlns="http: //www.w3.org/1999/xhtml">
<head>

<titlе>Динамическое перемещение элементов</titlе>
<style>
#headblock {
position: absolute:
left: 25px:
top: lOOpx:
width: 200px: }
</style>
</head>
<script type="text/javascript">
{ x = x + "px" : У = У + "px"; headblock. style. left =
x: headblock. style. top = y;

</script>
<body>
<form>
<pre>
Введите координату x: <input type="text"
id="xcoord" /> '
Введите координату у: <input type="text"
id="ycoord" />
<input type="button" уа!ие="Поехали!"
onclick="moveHeading(xcoord.value, ycoord.value)" />
</pre>
</form>
<div id="headblock">
<h1>Пеньe без My3ыки</h1>
<p> Когда ты вспомнишь обо мне в краю
чужом -- хоть эта фраза всего лишь вымысел,
а не пророчество, о чем для глаза, вооруженного
слезой, не может быть и речи: </р>
</body>
</html>

Надо ли объяснять, что пользователь вводит значения координат — и текст стихотворения перемещается на новое место? Довольно интересно, но еще интереснее было бы сделать, чтобы текст время от времени сам куда-нибудь убегал. Что касается того, как выглядит созданная нами страница, это можно увидеть на рис. 19.9.

Но почему же это не будет работать в Netscape? В основном потому, что там ио| пользуется несколько иная система доступа к элементам DOM. Чтобы можно было просмотреть созданную страницу в Netscape 6 (и IE 5.5 и выше), необходимо внести в листинг следующие изменения:

 function moveHeading(x, y) 
{
headblock = document. getElementByldC'headblock");
x = x + "px" : у = у + "px":
headblock.style.left = х: headblock.style.top = у:

Рис. 19.9. Вводим значения, нажимаем кнопку «Поехали!», и целый слой переезжает
на новое место

Все дело в том, что Netscape 6 использует официально рекомендованный консорциумом W3C подход к адресации объектов DOM. А браузеры 4-го поколения от Microsoft автоматически помещают все поименованные элементы в объект document. Смешанный подход заключается в том, чтобы вначале определять, ка кой браузер установлен у пользователя, а затем соответствующим образом задавать объектную переменную (headt>lock=). Мы обсудим это подробнее чуть позже.

ПРИМЕЧАНИЕ

То, что подходы у Netscape 6 и IE4 разные, не означает, что первый — «неправильный». Он как раз по сути своей ближе к рекомендациям W3C. Да и IE 5.5, на самом-то деле, имеет поддержку метода getElementBy!d(). Просто если вы хотите, чтобы и пользователи IE4 могли увидеть вашу блестящую технику написания сайтов, то придется воспользоваться соответствующими методами.

Видимость элементов CSSP

Стандарт CSSP привнес в определения стилей еще один новый параметр: visi bi1ity. Ero возможные значения таковы: visible, hidden, значением по умолчанию являст-ся auto. Вы просто указываете с помощью этого атрибута, хотите ли вы видеть дан ный элемент на своей странице или нет. А если да, то когда: всегда или только когда он не скрыт верхним слоем «бутерброда» из других элементов.

 #mydivl {
position: absolute;
left: 25px; top:
lOOpx; height: ЗООрх;
width: 200px:

visibility: hidden
}

Ну и не увидите вы никогда элементы, заключенные в соответствующий <di v>. Если таким способом изменить листинг 19.7, то в результате вы получите то, что показано на рис. 19.10. Как видите, ушел в небытие, скрылся в невидимых мирах первый абзац, определенный в листинге при помощи идентификатора mydivl.

Рис. 19.10. Первый <div> спрятался. На странице видна лакуна

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

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

ПРИМЕЧАНИЕ

И снова приходится упоминать о том, что этот пример — только для тех, кто до сих пор пользуется IE 4.0 (и выше — но только до 5.5).

Листинг 19.9. Использование свойства visibility для создания сменного содержимого страниц

<!DOCTYPE html PUBLIC "\//W3C//DTD XHTML
1.0 Transitional//EN" I -http://www. w3.org/TR/xhtmll/
DTD/xhtmll-transitional .dtd"> <html xmlns=
"http://www. w3.org/1999/xhtml ">
<head>
<titlе>Переменная видимость</titlе>
</head>
<style type="text/css">
#mydivl {
position: absolute: left: 50px: top: 50px; width:
SOOpx; height: 400px; visibility: visible:
#mydiv2
position: absolute: top: 50px; left: 50px: height:
400px: width: 500px: visibility: hidden:
</style>
<script>
<!--
function changeVist ) {
if (mydivl. style. visibility != "hidden") { mydivl. style.
visibility = "hidden": mydiv2. style. visibility = "visible":
else
mydivl. style. visibility = "visible": mydiv2.
style. visibility = "hidden":

</script>
</head>
<body>
<form>
<input type="button" value="HaiMM меня" onclick=
"changeVis()" />
</form>
<!-- Начинается первый слой -->
<div id="mydivl"> <img src="1980main.jpg" />
<р>Этот прекрасный загородный дом
расположен а саном сердце старого города.
Это придает ему особую прелесть, потому что.
имея во дворе чудесный вишневый сад,
</р>

<!-- Кончился первый слой -->
<!-- Начинается второй слой -->
<div id="mydiv2">
<img src="1730maple. jpg" />
<р>Рядом с этим доном расположены не только
хорошие школы и парк с раскидистыми кленами,
но и прекрасные утоптанные дорожки.
<!-- Кончился второй слой -->
</body>
</html>

Здесь мы снова создали два элемента <div> и в качестве начальной установки определили, что первый из них будет спрятан. По нажатию кнопки пользователь может спрятать то, что раньше было видно, а вместо этого увидеть то, что раньше было спрятано. Это делается у нас с помощью специальной функции, меняющей параметр visibility у слоев. Таким образом получается, что содержимое страницы — сменное. Мы как будто меняем кадры диафильма. В браузере это будет выглядеть так, как показано на рис. 19.11, но я тем не менее советую попробовать записать листинг в какой-нибудь файл и протестировать страницу на своем компьютере.

Рис. 19.11. Исходная страница (сверху) и та же страница после нажатия кнопки (снизу)

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

 function changeVisO {
mydivl - document.getElementByld ("mydivl").style:
mydiv2 - document.getElementByld ("mydiv2").style:
if (mydivl.style.visibility != "hidden") { mydivl.style.
visibility = "hidden";
mydlv2.style.visibility = "visible":
else {
mydivl.style.visibility = "visible": mydiv2.style.
visibility = "hidden":
}

ПРИМЕЧАНИЕ

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

Слои Netscape

В Netscape 4.x используется несколько иной подход к слоям. Там имеется элемент <1ауег>. Он никогда, впрочем, не имел особой популярности и так и не был принят в состав стандартных элементов HTML/XHTML. Ко времени выхода в свет 6-го поколения браузеров создатели Netscape смирились с такой участью <lауег> и стали больше смотреть в сторону позиционирования и создания слоев на основе CSSP, оставив этот элемент лишь для совместимости.

Между <lауег> и CSSP есть ряд принципиальных разногласий. Будем говорить сейчас об элементе <l ауег>.

  • При его использовании совершенно не требуется заранее определять стиль. Тем не менее у стиля есть id, однако устанавливается он не так, как в CSSP.
  • Он работает так же, как любые другие элементы веб-страницы, то есть такие параметры, как id, top, left являются обычными атрибутами. Это касается и синтаксиса. Используется знак равенства, за которым следует значение в кавычках. Никаких двоеточий и точек с запятой, как в определениях стилей, не нужно.
  • Имеется атрибут src, с помощью которого можно в качестве слоя использовать целую веб-страницу. При этом есть параметры раgех и раgеу, не имеющие аналогов в CSSP.

Вам уже знаком подход CSSP к позиционированию элементов, поэтому, мне кажется, <lауег> не должен казаться жутко незнакомым. Пример приведен в листинге 19.10.

Листинг 19.10. Слои Netscape и позиционирование

<html xmlns="http: //www. w3.org/1999/xhtml ">
<head>
<title>Подход Netscape к созданию слоев</title>
</head>
<body>
<layer id="mydivl" top="50" left="50">
<img src=" 1980main.jpg" />

<р>Этот прекрасный загородный дом
расположен в самом сердце старого города.
Это придает ему особую прелесть. </р>
</lауег>
<lауег id="mydiv2" top="500" left="50">
<img src="1730maple.jpg" />
<р>Рядом с этим домом расположены не только
хорошие школы и парк с раскидистыми кленами,
но и прекрасные утоптанные дорожки. </р>
</lауег>
</body>
</html>

Как и <div>, контейнер <lауег> включает в себя весь текст и разметку, которая должна войти в слой. В отличие от <div>, изменения стилей организуются с помощью атрибутов <lауег>, без каких-либо специальных определений таблиц стилей. Позиционирование — абсолютное по натуре своей: указываемые координаты отсчитываются относительно окна браузера.

Вы уже успели заметить некоторые атрибуты элемента <lауег>. Ниже приведен полный список с описаниями.

  • Id. С помощью этого атрибута задается уникальный идентификатор.
  • left и top. Координаты левой верхней точки слоя относительно «родительского» объекта.
  • Позиционирование с помощью этих атрибутов осуществляется так же, как и в CSSP. Единицы измерения по умолчанию — пикселы, поэтому спе циально указывать рх не требуется.
  • радех и радеу. Эти атрибуты позволяют задать расположение слоя, основываясь на размерах целой страницы, даже если родительский объект представляет собой нечто иное. (Имеется в виду, если <lауег> вложен в другой элемент.)
  • src. Внешний файл, используемый в качестве содержания слоя.
  • width и height. Размеры слоя. Единицы измерения по умолчанию — пикселы,но это могут быть и проценты (height="50%").
  • clip. С помощью cliр можно указать часть слоя, которая будет видна. Значения отступов, как обычно, следуют в таком порядке: левый, верхний, правый, нижний. Например: с11р="5.5,100.100".
  • z-Index. Уже знакомый атрибут. Позволяет задать порядок следования слоев. Чем больше значение, тем выше будет находиться слой.
  • visibility. Опять же, как и в CSSP, свойство visibility определяет видимость слоя и может иметь три значения: show, hidden и inherit. Последнее означает наследование свойства видимости у родительского объекта.
  • bgcolor и background. Да-да, можно задать цвет фона для слоя. Да и не только цвет (в шестнадцатеричном формате или с помощью названия), но и URL фонового изображения!

В дополнение ко всему этому следует упомянуть контейнер <nolауег>, содержимое которого будет выведено на экран в том случае, если браузер не имеет поддержки элемента <lауег>. Пример:

 <nolауег>Эта страница лоступна для просмотра
только в браузерах Netscape 4.0 или выше. </nolayer>

Внутристрочные слои Netscape

Это ответ Netscape относительному позиционированию элементов CSSP. Технически он реализуется с помощью элемента <Ilауег>, который задает так называемый внутренний, внутристрочный слой. На самом же деле, как и при относительном позиционировании в CSSP, <ilауег> начинается там, где его содержимое могло бы быть, не будь этого элемента. И относительно этого места экрана ведется отчет параметров top и left. Примером может служить следующий отрывок кода:

<body>
<р>0бычный абзац XHTML.</р>
<ilayer id="para2" left="10">
<p>А это - необычный абзац. Он сдвинут относительно
своего нормального местоположения на 10
пикселов вправо.</р> </ilayer>
<р>А это снова обычный абзац, он находится на своем
"законном" месте.</р>
</body>

Программная обработка слоев Netscape

Для манипулирования слоями Netscape можно использовать любой язык написания скриптов, например JavaScript. Объектная модель, правда, слегка отличается от используемой в CSSP (впрочем, она отличается и в зависимости от браузера), поэтому запутаться очень легко. К счастью, хотя бы доступ к свойствам слоев Netscape не является проблемой. Структура его такова:

Имя_слоя .Имя_свойства

В Netscape имеется множество методов работы с <lауег>, доступ к ним осуществляется следующим образом:

 Имя_слоя .Имя_метода()

В отличие от многих объектов и элементов Netscape 4, слои могут динамически изменяться. Можно их применять и в Netscape 6, хотя свойства CSSP также не запрещают этого и при этом ближе к «межплатформенности».

Свойства объекта layer практически повторяют атрибуты соответствующего эле мента. Единственная существенная разница заключается в применении clip, па раметры которого адресуются по отдельности: layerl.clip! eft, layerl.cliptop, erl.clipright и layerl.clipbottom.

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

document. layers [" layerl" ]

Oчень часто бывает удобно завести новую объектную переменную, чтобы рабо-[татьнепосредственно с ней. Это делается при помощи обычного присваивания:

МyLayer = document. layers["layerl" ]:

Теперь можно спокойно обращаться к свойствам и методам данного слоя: MyLayer.top = 5:
У самого объекта layer есть ряд методов, которые не имеют аналогов в CSSP. Они применяются для непосредственного манипулирования слоями, их перемещения и установки видимости. В таблице 19.2 показаны эти методы.

Таблица 19.2. Методы объекта layer

Метод Описание
moveBy(x, у) Сдвигает слой на указанное число пикселов
moveTo(x, у) Сдвиг на указанные координаты (относительно родительского объекта)
moveToAbsolute(x, у) Сдвиг на указанные абсолютные координаты
геsizeВу (ширина, высота) Увеличивает/уменьшает слой на указанное число пикселов
геsizeТо (ширина, высота) Увеличивает/уменьшает слой до указанного числа пикселов
movеАbоvе (имя_слоя) Помещает данный слой над указанным в скобках

movеВеlоw (имя_слоя)
Помещает данный слой под указанным в скобках
load(src, ширина) Заменяет текущее содержимое на содержимое указанного файла


Имейте в виду, что в Netscape 4 изменение размеров слоя может привести к несколько неожиданным результатам. Оно там работает, больше напоминая clip, то есть просто делает невидимой часть слоя за пределами границ. Методы следует использовать совершенно обычным способом (привычным для JavaScript):

 layerl.resizeTo(250. 500):

Ну, теперь вы уже готовы к непосредственному применению JavaScript. В следующем примере будет использован тот же подход к перемещению слоев, что и в лис тинге 19.9, где было задано два объекта, и по нажатию кнопки они меняли свое свойство видимости. В листинге 19.1 1 примерно то же самое делается с применением элементов <lауег>.

Листинг 19.11. Изменение видимости слоев

 <!DOCTYPE html PUBLIC "\//W3C//DTD XHTML
1.0 Transitional //EN"
"http://www.w3.org/TR/xhtmll/DTD/
xhtittll-transitional .dtd">
<html xmlns="http: //www.w3.org/1999/xhtml">
<head>
<titlе>Слоеный веб-пирог и Netscape</title>
<script>
<!--
function changeLayer( ) {
window .alert (document . mydivl.visibility):
if (document. mydivl. visibility != "hide")
{
document. mydivl. visibility = "hide":
document. mydiv2. visibility = "show":
}
else {
document. mydivl. visibility != "show";
document. mydiv2. visibility = "hide";
--> </script>
</head>
<body>
<form>
<input type="button" уаluе="Нажми меня"
onclick="changeLayer()" l>
</form>
<layer id="mydivl" top-"50" left="50">
<img src="1980main.jpg" />
<р>Этот прекрасный загородный дом
расположен в самом сердце старого города.
Это придает ему особую прелесть, потому что.

имея во дворе чудесный вишневый сад. вы в то
же время будете обеспечены всеми благами
цивилизации. Поблизости расположена старая
добрая аптека, а также лечебный фонтан!
Сделайте свою жизнь такой, как вам нравится,
всего лишь за $125 000.</р>
</lауег>
<lауег id="mydiv2" top="50" left="50" visibility="hide">
<img src="1730maple.jpg" />
<р>Рядом с этим домом расположены не
только хорошие школы и парк с раскидистыми
кленами, но и прекрасные утоптанные дорожки.
</р>
</lауег>

</body>
</html>

Очевидно, что этот скрипт очень похож на аналогичный пример, сделанный с расчетом на CSSP. Здесь лишь использован элемент <lауег>, присущий известно какому браузеру, а также его же объектная модель. Но на самом деле, как вы увидите дальше, все это можно совместить и в одной странице.

Пример страницы с DHTML, не зависящей от браузера

Вот мы и подобрались к вопросу, который уже давно волнует общественность в лице моего читателя: «Да в конце-то концов, могу я сделать хоть что-нибудь, не зависящее от браузера? Хоть одну страницу, которая бы нормально работала и в IE, и в Netscape 4, и в Netscape 6?» Ответ будет утвердительный. Сейчас мы попробуем выявить общие свойства всех браузеров и собрать в одном примере то, что мы делали в листингах 19.9 и 19.11.

Для начала разберемся с Netscape 4. Я вас не очень удивлю, если скажу, что при нежелании использовать элемент <lауег> можно спокойно без него обойтись? А это действительно так. Вы забыли, что Netscape 4 очень хорошо понимает, что значит элемент <di v>? Забыли, что идентификаторы можно задать и в секции <style>? Вот каким будет пример DHTML, который распознают все три браузера:

<style type="text/css">
#mydivl {
position: absolute; left: 50px; top: 50px: width: 500px:
height: 400px: visibility: visible; }
#mydiv2 {
position: absolute: top: 50px: left: 50px; height: 400px;
width: 500px: visibility: hidden; }
</style>

Нет сомнений, что любой браузер воспринимает контейнер <body>. Тогда почему же возникают сомнения, будто кто-то из них не будет поддерживать <div> н обработку события onelick.
Хм... В чем же тогда отличие между браузерами? Собственно говоря, только в функ ции, которая меняет слои. Она отличается по следующим причинам:

  • Каждый браузер обращается к объектам document по-своему. 1Е4 (н выше) поддерживает синтаксис document.all .имя_слоя; в Netscape 6 используется такой: document.getElementByld("имя_слоя"), а в Netscape 4 вы встретите еще один вариант: document. имя_слоя.
  • Netscape 4 может, конечно, присвоить свойству visibility значения visible или hidden, однако проверять-то он будет его на значения show или hide. Об этом не следует забывать.

ПРИМЕЧАНИЕ

С технической точки зрения IE 5.5 и выше должен поддерживать подход Netscape 6, однако это привело бы к размножению проверяемых типов браузеров. Вместо трех их стало бы четыре. В общем, поскольку IE 5.5 совместим с IE 4, мы считаем, что IE любой версии — Это одна и та же сущность.

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

 var isNet4:
var isNet6:
var isIE;
if (navigator.appName == "Netscape") {
if (navigator.appVersion.charAt(O) == 4) isNet4 = true:
if (navigator.appVersion.charAt(O) == 6) isNet6 = true:
}
if (navigator.appName.indexOfC'Microsoft") != -1)
isIE = true:

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

1. Для начала создаются три переменные, которые соответствуют трем типам тестируемых браузеров.

2. Проверяется имя приложения.

3. Если именем является «Netscape», то нужно проверить его версию. В зависимости от этого устанавливается значение true либо переменной 1sNet4, либо isNet6.

4. Если же в имя приложения входит слово «Microsoft», то сразу становится все понятно. Дальше можно ничего не проверять, а установить в true переменную isIE. (Технически это сравнение производится с помощью метода IndexOf. Проверяется, является ли строка "Microsoft" частью имени браузера. Если этот метод возвращает значение, отличное от 1, значит, это так. Способ несколько запутанный, но зато работает.)

5. Теперь мы можем заняться написанием функции, которая, в зависимости от результатов произведенной проверки, выберет, что делать дальше. Здесь мы должны включить в состав переменных visTest, которая будет содержать строку, соответствующую свойству visibility. (Проблема, напомню, в том, что при тестировании видимости для Netscape 4 возможными значениями являются hi de и show, а не hidden и visible. Вместе с тем эти значения просто не будут распознаваться при обработке, а присвоить-то их никто не запрещает. Поэтому никакие уступки Netscape 4 в секции, непосредственно меняющей местами слои, не нужны.)

6. Затем создаются две объектные переменные (divlObject и div20bject), которые призваны исключить разницу в восприятии браузерами свойства visibiIity:

 van visTest; var divlObject: van div20bject:
if (isNet4) { visTest = "hide": divlObject = document.mydivl: div20bject = document.mydiv2; }
if (isNet6) { visTest = "hidden":
divlObject = document.getElementByldt"mydivl").style: div20bject
= document.getElementById("mydiv2").style: }
if (isIE) {
visTest = "hidden":
divlObject = document.all.mydivl.style:
div20bject = document.all.mydiv2.style:
}

Функция закапчивается тем же самым программным «пассажем», который вы видели и в листинге 19.9, и в 19.11. Свойство visibility тестируется, выясняется, не является ли первый слой скрытым. Если не является, то он скрывается, а показывается второй слой. Если же первый слой скрыт, происходит обратное.

 if (divlObject.visibility != visTest) { divlObject.visibility = 
"hidden":

</body>
</html>

Межбраузерный программный интерфейс (API)

В предыдущем параграфе вы наблюдали, как довольно большая программа в o6 щем-то выполняет не такую уж большую работу. Можете себе представить, что будет, если вы попытаетесь написать серьезное веб-приложение с множестве функций? Хотя вполне приемлемо писать подобные вспомогательные функции распознавания браузеров и обобщения своих скриптов путем создания специальных указателей на конкретные элементы DOM, все-таки более грамотным и целе сообразным решением было бы использование специального программного интерфейса приложений (АРГ).

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

Звучит заманчиво, не правда ли? Чтобы узнать больше, посетите один из следующих сайтов:

  • http://www.mozilLa.org/docs/Be6-developer/csspapi/csspapi.html. Компания Mozilla-разработчик ядра браузера Netscape — предлагает совершенно бесплатно скачать межбраузерный API для JavaScript.
  • http://dynapi.sourceforge.net/dynapi/. DynAPI — это примерно то же самое, что в API для совмещения различных браузеров, однако включает в себя еще и некоторые дополнительные функции для упрощения работы с DHTML.

Динамические стили и классы

Теперь, когда вы знаете, как с помощью скриптов изменять позиционирование элементов (CSSP), вы запросто освоите динамическое программирование CSS.

И это действительно несложно! Впрочем, лишь до тех пор, пока вы не возьметесь подгонять свои скрипты под Netscape 4. Как вы ни будете стараться, ничего у вас не получится, потому что этот браузер, в принципе, не умеет динамически изменять страницы. Меж тем IE 4 это умеет, не говоря уж о более свежих версиях. Так получилось, что только к 6-й версии Netscape обрел эту замечательную возможность. Зато можно с уверенностью сказать, что начиная с этого уровня оба браузера заметно сблизились.

Между прочим, мы сейчас с вами говорим о программировании CSSL, потому что возможности CSSP считаются принадлежностью CSS2. Что до CSS1, так это уже давно устоявшийся стандарт, о котором шла речь в главе 10. Вы, должно быть, по- мните font, text, border и прочие свойства. В этом разделе мы рассмотрим программирование CSSL для IE 5.5 и выше, Netscape 6 и совместимых с ними браузеров.

Программирование стилей и свойств

Учитывая все имеющиеся у вас знания, не хочется даже особо комментировать такие очевидные вещи, как те, что вы сейчас увидите. Например:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>динамические изображения</title>
</head>
<script type="text/javascript">
function changeText (p) {
p.style.color="red":
</script>
<body>
<p onmouseover="changeText(this)">
TecT l1</p> <p onmouseover="changeText(this)">
TecT 2</p>
</body>
</html>

Если поместить указатель мыши на один из тестовых абзацев, цвет текста изменится на красный. Стиль меняется с помощью простого присваивания в обработчике событий: p.style.color="red".

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

Листинг 19.13. Изменение цвета текста

 <!DOCTYPE html PUBtIC "V/W3C//DTD XHTMt 
1.0 Transitional//EN"
"http://vjww.w3.org/TR/xhtmll/DTD/
xhtmll-transitional .dtd">
*tml xmlns="http://www.w3.org/1999/xhtml ">
<head>
<title>Динамическое изменение цвета</title>
</head>
<script type="text/javascript"> продолжение •&
function changeBack () {
var theColor = document. forms[0].myColor.
value:
alert (theColor) ;
document. getElementByldC'myPara").
style. color = theColor:
if (theColor == "white") document. body.

style. backgroundColor = "black"
</script>
<body style="background-color: gray">
<form name="forml">
<p id="myPara">KaKMM цветом
раскрасить текст?</р>
<input type="text" name="myColor" />
<br />
<input type="button" уа!ие="Изменить"
onclick="changeBack()" />
</form>
</body> </html>

В этом примере пользователь может самостоятельно ввести цвет в поле ввода myCol or, затем щелкнуть на кнопке Изменить. При этом вызовется функция changeBack( ). Что происходит в этой функции? Введенное пользователем значение перехватывается и присваивается переменной theCol or, после чего определяется стиль всего абзаца. Функция также проверяет, не установлен ли цвет текста белым. В этом случае цвет фона изменяется на черный.

ПРИМЕЧАНИЕ

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

Динамические классы и идентификаторы

В предыдущем параграфе вы узнали, что, оказывается, можно изменять отдельные свойства элементов, невзирая на то, какими они были. А что, если поменять не свойство, а сам идентификатор класса, изменив тем самым сразу несколько параметров? Ничего сложного в этом нет, и вы сами можете в этом убедиться, изучив листинг 19.14.

Листинг 19.14. Динамическое изменение классов CSS

 <!DOCTYPE html PUBLIC "V/W3C//DTD XHTML 
1.0 Transitional//EN"
"http://www.w3.org/TR/xhtmll/DTO/
xhtmll-transitional .dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Динамические классы</title>
<style>
.big {font-size: 36: color: red}
.snail {font-size: 12: color: black}
</style>
<scrlpt type="text/javascript">
function changed ass() {
theClass = document. getElementByldC'myPara")
.className:
alert (theClass):
if (theClass != "big") {
document. getElementById("myPara")
.className = "big":
}
else document. getElementByldC'myPara")
.className = "small":
</script> </head>
<body>
<form name="forml">
<p id="myPara" сlass="small">Каким стилем
оформим текстик?</р> «input type=" button"
vаluе="Изменить" onclick="changeClass()" />
</form>
</body>
</html>

Итак, что мы имеем? Пользователь щелкает на кнопке Изменить, запуская тем самым функцию. В ней определяется текущее имя класса, используемого в качестве стиля абзаца. Оно присваивается переменной theClass. Потом проверяется, не является ли big значением theCl ass. Если не является, то именно это значение и присваивается. В противном случае theClass объявляется равным small. Таким образом скрипт при каждом нажатии на кнопку меняет стиль текста.

Это показано па рис. 19.12.

Рис. 19.12. Исходная страница (сверху) и та же страница после нажатия на кнопку (снизу). Изменился класс, а значит, и стиль текста

Резюме

Тесное сотрудничество технологий JavaScript и CSS дает результат, называемый Dynamic HTML. В те времена, когда Netscape и Internet Expolrer выпустили свои 4-е версии браузеров, аббревиатура DHTML просто не сходила с уст веб-разработчиков. Стараний было много, однако, как потом оказалось, очень во многом браузеры оказались несовместимыми друг с другом. Это, увы, замедлило процесс распространения DHTML.

Обе компании затем выпустили браузеры 5-го и 6-го поколений, и вот тогда картина уже несколько изменилась. Наконец-то в Netscape и Internet Explorer можно было найти поддержку CSS, причем как для создания стилей, так и для определения размещения элементов. Стало возможным программирование многих параметров стилей. И все стандартные браузеры стали воспринимать существующую действительность более или менее одинаково.

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

В конце главы мы рассмотрели вопросы программирования CSS1, включая изменение отдельных параметров стиля, так и целых классов.

Следующая глава будет посвящена некоторым популярным редакторам HTML и XHTML. Вы узнаете о некоторых различиях между ними и преимуществах ис пользования графических редакторов.

Главные новости:

®Abifost, 2006. Копирование информации сайта разрешается только с указанием ссылки на этот сайт. Гостевая книга Контакты, резюме, об авторе
Hosted by uCoz