Начало · Справочники · Курсы · Разговоры

leechy.ru · Сайт почти придуман

Слои

Сразу после появления 4-х Netscape Navigator и Microsoft Internet Explorer в 1997, считалось, что dHTML — это в основном работа со слоями. В настоящее время я (и не только) считаю, что слои должны выполнять вспомогательные функции и не стоит возводить их в ранг единственных элементов с которыми нужно работать. Но прежде всего, я расскажу что такое «слои».

Что это такое?

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

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

С помощью слоев можно делать всякие всплывающие/выпадающие меню, полупрозрачные отображения перетаскиваемых элементов и прочие т. н. «eye-candies».

Немного истории

Перед выходом NN4 (и последующим выходом MSIE4) появляется рабочая версия (working draft) спецификации под названием «Positioning HTML Elements with Cascading Style Sheets» (известная как CSS-P). Эта спецификация так и не стала рекомендацией, потому что вошла в состав CSS level 1, но все еще может быть найдена на сайте W3C.

Это первая и последная, известная мне, попытка Microsoft и Netscape договориться о том, как реализовать новую технологию в новых версиях браузеров. Ее авторами стали Скот Фурман (Scott Furman) из Netscape и небезизвестный Скот Айзакс (Scott Isaacs) из Microsoft (написавший книгу Inside dHTML и основавший одноименный сайт, который нынче называется The SiteExperts.Community).

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

В первом случае, когда элемент расположен относительно других элементов в HTML-потоке, он занимает свое обычное место на странице и взаимодействует с остальными элементами так, как будто он самый обычный элемент. Особенность состоит в том, что он может быть изображен «со смещением» по отношению к остальным элементам страницы, т. е. относительно. Несмотря на то, что есть множество примеров использования относительно позиционированных элементов, как правило их не используют по прямому назначению. Лично мне они нужны только для определения положения конкретного элемента страницы в NN4.

Второй случай — абсолютно позиционированные элементы и есть слои.

Как сделать слой с помощью HTML?

Очень просто. Разглагольствовать о том, что в MSIE нужно использовать <div>, а в NN4 — <layer> не буду — это не так. Нужно просто использовать CSS (чуть было не написал CSS-P ;-)).

Итак, чтобы сделать слой, который отступает на 100px от левого верхнего угла страницы нужно написать следующий код:

<div style="position: absolute; left: 100; top: 100;">Содержание слоя</div>

Этот код будет работать во всех браузерах выше 4-й версии, даже в Опере и в NN6/Mozilla.

Как сделать слой с помощью JavaScript?

Есть возможность сделать слой даже после окончательной загрузки документа. Конечно, это уже не так безболезненно, как в HTML'е. Не так совместимо. И... не так просто.

Netscape Navigator 4

Слой для NN4, это особый объект как, например изображение. И создается он как обычный объект JavaScript — с помощью функции, которая называется Layer(). Только из-за ограничености браузера при рендеринге чего бы то нибыло, еще в самом начале нужно указать ширину этого слоя. Работа со слоями в NN4 осуществляется только через колекцию document.layers, поэтому мы создадим новый слой таким образом:

document.layers['имя_слоя'] = new Layer(n);

где n — ширина слоя в пикселах.

Отдельно нужно сказать, что содержание и положение слоя на странице нужно указывать после его создания. Положение, используя свойства top и left:

document.layers['имя_слоя'].top = 100;
document.layers['имя_слоя'].left = 100;

А содержание, используя стандартные функции open(), write() и close():

document.layers['имя_слоя'].document.open();
document.layers['имя_слоя'].document.write('Содержание слоя');
document.layers['имя_слоя'].document.close();

Как видно из примера, NN4 воспринимает слой как отдельный документ и к его содержание обращается через внутренный объект document этого слоя — document.layers['имя слоя'].document. Это важная особенность, которая многие не учитывают при создании вложенных слоев, к которым нужно обращаться через их родителей:

document.layers['имя_слоя'].document.layers['имя_вложенного_слоя']

Microsoft Internet Explorer 4

В отличие от NN4, для MSIE4 слои — это такие-же элементы, как и все остальные (т.е. это не специальные объекты). Но из-за слабой объектной модели новый слой нужно добавлять в конец страницы как обычный HTML-код, с помощью специальной функции insertAdjacentHTML(). А для того, чтобы указать, что это не обычный статический элемент, нужно указать абсолютное позиционирование:

document.body.insertAdjacentHTML('<div id="имя_слоя" style="position: absolute;">Содержание слоя</div>');

При этом, если в стиле не указана ширина слоя (style="width: 150;"), то она не определяется в зависимости от содержания, по-умолчанию она 100% от ширины окна.

DOM-совместимые браузеры

Это браузеры MSIE5+ и NN6/Mozilla. Насколько мне известно, несмотря на заявления поддержки DOM в Опере это работать не будет.

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

DOM-метод для создание элемента — это document.createElement(). С эго помощью можно создать любой элемент в соответствие с DTD, который используется на странице. В нашем случае это будет <div>:

var newLeer = document.createElement('div');

Новый элемент создан и записан в переменную newLeer. Теперь нужно указать его имя и положение. Имя указывается с помощью стандартного метода setAttribute(), а положение — через объект стилей, который есть у любого HTML-элемента:

newLeer.setAttribute('id','имя_слоя');
newLeer.style.position = 'absolute';
newLeer.style.left = 100;
newLeer.style.top = 100;

После этого нам нужно создать содержимое слоя. Если это HTML-элементы, то нужно воспользоваться того-же метода document.createElement(), а если это просто текст, то нужно создать textNode с помощью метода document.createTextNode():

var newLeerContents = document.createTextNode('Содержание слоя');

В итоге у нас есть две переменные: newLeer и newLeerContents. Необходимо положить содержимое в слой и в свою очередь слой в документ. Для этого есть еще один DOM-метод — appendChild():

newLeer.appendChild(newLeerContents);
document.body.appendChild(newLeer);

Вуаля! Следует резонный вопрос: Стоит ли так извращаться? И правильный ответ: Стоит! Это правильный способ работы с документами. Он подходит для практически всех видов документов от простого HTML до XML. Над методами работы с DOM'ом я буду останавливаться подробнее в следующих статьях и надеюсь все убедятся в том, что работать с ними гораздо логичнее и легче, чем использование «халявных» методов. Как пример халявного метода — вместо создание textNode можно написать просто:

newLeer.innerHTML = 'Содержание слоя';

Но мы разве ищем легких путей? ;-)

Что дальше?

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

Дальше будет еще одна «обзорная» статья в которой опишу что такое события и маленький пример drag'n'drop элементов страницы.