Введение
Появление
Dynamic HTML сопровождалось всеобщей эйфорией. Было обещано, что данная
технология станет одной из самых актуальных новинок для веба. Возможно, так оно
и есть: DHTML действительно позволяет создавать ошеломляющие веб-сайты, полные
интерактивности, анимации и спецэффектов. Его можно применять для разработки
серьезных веб-приложений, мультимедийных презентаций и замечательных игр.
Однако, хотя с момента появления DHTML прошло уже больше года, этот язык, к
сожалению, так и не стал по-настоящему популярным. Из миллионов веб-сайтов DHTML
использует всего горстка, да и те в основном лишь прикасаются к его основам.
Что же мешает DHTML взять настоящий старт? Ответ прост: Microsoft Internet
Explorer и Netscape Navigator поддерживают разные версии технологии, и
разработчики не хотят программировать все по два раза. Но мы покажем, как
создать DHTML-страницы, которые работают и в Internet Explorer, и в Navigator.
Достигается это за счет использования общих свойств версий DHTML IE 4.0 и
Navigator 4.0.
Элементы-контейнеры DHTML опирается на сочетание
трех технологий: HTML, каскадные таблицы стилей (Cascading Style Sheets, CSS) и
сценарии. HTML служит для определения таких элементов веб-страниц, как текст и
таблицы. CSS применяется для задания стиля и позиционирования элементов. А при
помощи сценариев осуществляется взаимодействие с элементами и их модификация.
В идеальном мире все эти технологии следовало бы применять для
манипулирования любыми элементами веб-страниц. Но из-за различных способов
интерпретации DHTML браузерами IE и Navigator для каждого элемента приходится
создавать контейнер и манипулировать не самим элементом, а этим контейнером. В
качестве такого контейнера мы рекомендуем использовать элемент <DIV>.
Почему <DIV>, который обычно используется в таблицах стилей для
разделения областей с разными стилями? Из <DIV> получается единый
контейнер, которым можно манипулировать как в Internet Explorer, так и в
Navigator. Вместо того, чтобы работать с отдельными элементами: абзацами,
таблицами и т. п., - вы создаете контейнеры <DIV>, добавляете к ним
элементы, а затем манипулируете этими контейнерами целиком. Чтобы обращаться к
контейнерам в кросс-браузерной среде DHTML, им необходимо присвоить имена.
Поэтому снабдите контейнер <DIV> атрибутом ID, например: <DIV
id="mycontainer">.
Кроме того, нужно определить положение каждого из контейнеров, которыми вы
собираетесь манипулировать в DHTML. Это делается одним из двух способов: методом
абсолютного или относительного позиционирования. Абсолютное позиционирование
определяет точное положение контейнера. Например, можно указать, что контейнер
будет находиться в 25 пикселях вправо от левой границы главного окна и в 50
пикселях вниз от его верхней границы. При относительном позиционировании
контейнер позиционируется относительно места его определения на веб-странице.
Например, он может следовать за третьим элементом страницы и иметь протяженность
200 пикселей.
Положением контейнера по горизонтали (его координатой х) управляет
CSS-атрибут left, а его положением по вертикали (координатой y) - атрибут top.
Кроме позиционирования элементов на плоскости, можно использовать ось z
(элементы могут накладываться один на другой как на трехмерном изображении).
Присваивая контейнеру более высокий z-индекс, вы помещаете его перед другим
элементом.
Z-индекс обычных элементов страницы равен нулю. Значения z-индекса в IE могут
быть положительными и отрицательными целыми числами. Но в Navigator z-индекс
должен быть нулем или положительным целым числом. Поэтому для универсальных
страниц необходимо использовать только положительные или нулевой z-индексы.
На рис. 1 показано, как указать значения координат x, y, z для двух
контейнеров. Первый расположен на 50 пикселей правее левой границы главного окна
и на 100 пикселей ниже его верхней границы в абсолютных координатах. Второй
контейнер находится на 50 пикселей правее левой границы главного окна в
относительных координатах. Z-индексы обоих контейнеров равны 2, так что они
расположены перед обычными элементами страницы. Так как первый контейнер
позиционирован в абсолютных координатах, на рис. 2 он расположен перед
изображением, тогда как контейнер, позиционированный в относительных
координатах, находится за изображением.
<html>
<head>
<style type="text/css">
<!--
#abs { position: absolute;
top: 100px; left: 50px;
z-index: 2;
height: 50px; width: 150px}
#rel { position: relative; left: 50px;
z-index: 2; height: 50px;
width: 150px }
-->
</style>
</head>
<body>>
<img src="mugshot.jpg">
<div id="abs">
<p>Absolute positioning example!</p>
</div>
<div id="rel">
<p>Relative positioning example!</p>
</div>
</body>
</html>
Рис. 1. Эта страница иллюстрирует относительный и абсолютный методы
позиционирования контейнеров.
Рис. 2. К такому расположению элементов приводит код, представленный на рис.
1. Контейнер, позиционируемый в абсолютных координатах, заслоняет изображение, а
тот, что позиционирован в относительных координатах, расположен сзади.
Обращение к объектам Научившись создавать и
позиционировать контейнеры в IE и Navigator, пора разобраться в синтаксических
различиях между сценариями обращения к контейнерам обоих браузеров.
IE4 при обработке и манипулировании динамическими веб-страницами поддерживает
модель document object model. Каждый элемент веб-страницы представлен объектом,
управляемым посредством сценариев. Простейшим способом доступа к объекту
является использование его имени, присвоенного атрибутом ID. Чтобы обратиться к
контейнеру <div id="abs">, созданному кодом на рис. 1, следует
воспользоваться объектом abs.
Поставив в соответствие объекту его идентификатор в Internet Explorer, можно
управлять его положением, выделением и другими характеристиками посредством
соответствующего объекта стиля. Всеми динамическими изменениями объекта
управляет сценарий. Контейнер abs можно двигать, присваивая новые значения
параметрам его положения top и left, и менять его характеристики, манипулируя
параметрами стиля. Например, положение контейнера abs по горизонтали можно
изменить посредством объекта стиля abs.style.left следующим образом:
abs.style.left += 5;
Navigator 4 поддерживает другую модель - дерево объектов, в котором доступ к
элементам осуществляется в соответствии с их положением в дереве. Ключом для
обращения к тем или иным уровням объектов служит способность анализировать
структуру дерева. Корнем дерева является объект документа. Доступ к следующему
уровню осуществляется через объект уровней или по имени, присвоенному атрибуту
ID. Доступ к дочерним уровням всегда осуществляется через их родительские
уровни. Создав следующие контейнеры:
<div id="layer1">
<div id="a"><p> Layer 1-A</p></div>
<div id="b"><p> Layer 1-B</p></div>
</div>
можно установить атрибут left уровня 1 при помощи одного из операторов:
document.layers['layer1'].left += 5;
document.layer1.left += 5;
Положение уровня А по горизонтали нужно задать через уровень 1 одним из
следующих способов:
document.layers['layer1'].document.layers['a'].left += 5;
document.layer1.document.a.left += 5;
document.layers['layer1'].document.a.left += 5;
Как видно из приведенных примеров, необходимость анализировать дерево
объектов с несколькими уровнями довольно обременительна. Чтобы избавиться от
нее, следует избегать вложенных контейнеров и размещать каждый контейнер
независимо.
Так как атрибуты обращения к объектам в IE и Navigator отличаются, приходится
прибегать к условным операторам, определяющим синтаксис в зависимости от
браузера, при помощи которого просматривается страница. Один из способов
определения типа браузера - это применение атрибута navigator.appName,
проверяющего имя браузера, и атрибута navigator.appVersion, проверяющего его
версию. Однако более надежным решением служит проверка поддерживаемых объектов.
Объект document.layers поддерживает только Navigator 4.0 и выше, а объект
document.all - только Internet Explorer 4.0 и выше, так что достаточно
использовать условный оператор, который определяет наличие этих объектов и, в
зависимости от результата, выбирает соответствующий синтаксис.
В примере на рис. 3 создается простая текстовая анимация с применением
атрибутов object.style.left и document.object.left. Если обнаружен
document.layers, используется синтаксис Navigator. Если обнаружен document.all,
используется синтаксис IE. У object.style и document.object есть и другие важные
атрибуты, которыми интересно манипулировать: bgcolor задает цвет фона,
background - фоновое изображение, clip - обрамляющий прямоугольник, top -
положение по вертикали, visibility показывает контейнер или скрывает его, а
zIndex помещает контейнер перед элементами или за ними.
Обратите внимание на некоторые другие используемые в коде на рис.3 приемы
DHTML, такие, как способ определения текущего положения контейнера. Если
Navigator может получать координаты непосредственно, то Internet Explorer
способен извлекать их только через функцию parseInt(). Заметьте также, что для
запуска функции test() по окончании загрузки страницы используется событие
onload. Пока синтаксический разбор элементов не закончен, они отсутствуют на
веб-странице, поэтому необходимо дождаться onload или другого подобного события,
гарантирующего, что браузер уже обработал элемент, которым вы намерены
манипулировать.
Для более сложных манипуляций элементами потребуется обращение к объектам. В
следующем примере создается ссылка на объект, называемый MyMove, которая затем
применяется в нужной функции:
<!--
function getReady() {
if(document.layers) { MyMove = document.moving;
} else if (document.all) { MyMove = moving.style; }
test()
}
function test() {
MyMove.left = parseInt(MyMove.left) - 3;
if (parseInt(MyMove.left) < 0 ) { MyMove.left = 640 }
setTimeout('test()',200);
}
-->
Теперь следует заменить строку <body onload= "test()"> в примере на
рис. 3 строкой <body onload= "getReady()">.
Эта замена делает код более наглядным и позволяет обращаться к
соответствующему объекту из любой функции на странице без необходимости вновь и
вновь прибегать к условным переходам. В новой функции все значения параметров
позиционирования уже обработаны. Это гарантирует правильность ее выполнения как
в IE, так и в Navigator.
<html>
<head>
<script>
<!--
function getReady() {
if(document.layers) { MyMove = document.moving;
} else if (document.all) { MyMove = moving.style; }
test()
}
function test() {
MyMove.left = parseInt(MyMove.left) - 3;
if (parseInt(MyMove.left) < 0 ) { MyMove.left = 640 }
setTimeout('test()',200);
}
// -->
</script>
</head>
<body onload="getReady()">
<div id="moving" style="position: absolute; top: 100px; left: 50px;
z-index: 2; height: 50px; width: 150px ">
<h1>Moving text is cool!</h1>
</div>
</body>
</html>
Рис. 3. Этот код демонстрирует, как заставить текстовую анимацию работать как
в IE, так и в Navigator.
Другие тонкости кросс-браузерного
программирования При рассмотрении предыдущего примера может возникнуть
вопрос, зачем было включать параметры стиля в теги <div>? Дело в том, что
IE не способен читать некоторые параметры (clip, left, top и др.) из JavaScript.
Чтобы избежать необходимости использовать линейные стили и создавать длинную
веб-страницу, можно установить значения left и top прямо в JavaScript при помощи
параметров pixelLeft и pixelTop соответственно. Более красивый способ
заключается в том, чтобы заставить IE манипулировать не самим объектом, а
объектом правил таблицы стилей. Однако для этого требуется достаточный опыт по
созданию сценариев.
Internet Explorer - не единственный браузер, испытывающий проблемы с DHTML.
Известная ошибка Navigator 4.0 приводит к тому, что при изменении размеров окна
элементы теряют свои динамические свойства. Чтобы избежать этой проблемы, нужно
перезагружать страницу всякий раз, когда изменяется размер окна Navigator.
Делается это так:
if (document.layers) { window.onResize = reloadNow; }
function reloadNow() {
document.location = document.location;
}
Еще один прием, которым полезно овладеть, - динамическая замена контента. В
Internet Explorer для этого изменяют содержимое контейнера посредством функции
innerHTML. В Navigator контент меняют, открывая поток документа функцией
document.open(), записывая новый контент функцией document.write() или
document.writeln(), а затем закрывая поток функцией document.close(). Эти
средства IE и Navigator позволяют менять текст контейнера, перемещая ID:
if(document.layers) {
document.moving.document.open();
document.moving.document.write(" <h1>Hello!</h1>");
document.moving.document.close();
} else if (document.all) {
moving.innerHTML= "<h1>Hello!</h1>";}
И еще об изменении размеров окна браузера. С главным окном можно работать и
другим способом, используя объект screen. Чтобы изменять размер главного окна в
соответствии с характеристиками монитора пользователя, можно применить параметры
screen.height и screen.width. Первый определяет высоту экрана, второй - его
ширину. Для определения глубины цвета экрана служит параметр screen.colorDepth.
Все они поддерживаются как в Internet Explorer, так и в Navigator.
|