|
Динамическое позиционирование слоевВ разделе 8.1 мы рассмотрели навигацию по сайту с помощью
фреймов. Однако в последнее время использование фреймов становится все
менее популярным в связи с появлением технологии позиционирования слоев.
Давайте на том же самом примере сайта гипотетической фирмы «Лентяй» рассмотрим,
как организовать навигацию без использования фреймов. Одним из преимуществ
этого подхода является то, что нам не придется «разбрасывать» содержимое
по нескольким файлам. Все основное содержимое хранится в одном файле и,
следовательно, сразу же загружается на компьютер пользователя, так что
при переходе от раздела к разделу читателю не приходится каждый раз ждать
нового соединения с сервером и загрузки очередного документа. Переход
от раздела к разделу происходит практически мгновенно. (Правда, если разделов
слишком много или они изобилуют графическими элементами, то помещать их
все в один файл, наверное, не следует, так как время первоначальной
загрузки такого файла будет слишком большим.) Формирование слоевВообще говоря,
нечто подобное мы уже проделывали в главе 7 с «Домашней страницей Сергея
Сергеева». Но там мы просто произвольно изменяли содержимое элементов с помощью
свойств типа innerText. Здесь же мы применим другой подход. Создадим несколько
слоев, каждый из которых содержит HTML-код, одного из разделов сайта. В
нашем примере это разделы «Услуги», «Цены» и «Книга отзывов» (выше этим разделам
соответствовали отдельные файлы: main.html, prices.html и guestbook.html). Все
эти слои размещаются в одном и том же месте страницы, но в каждый момент времени
только один из них видим, а остальные — скрыты. Щелчок на гиперссылке приводит к
тому, что видимым становится другой раздел. Чтобы какой-то
слой стал невидимым, достаточно присвоить его стилевому свойству visibility
значение hidden (для Netscape — hide), а чтобы сделать его видимым, этому
свойству следует присвоить значение visible (для Netscape — show). Каждый слой
можно организовать с помощью тега <DIV>. Итак, попробуем
написать код. В начале файла мы просто полностью вставим таблицу стилей, уже
использованную нами ранее для этого сайта. Правда, селектор .lnk А можно из нее
исключить, так как все гиперссылки на разделы, как вы, вероятно, уже догадались,
будут мнимыми, то есть в них не будет использоваться тег
<А>. Потом следует
написать функции JavaScript. Прежде всего, мы поместим туда ранее написанные
функции для работы интерактивного прайс-листа и пока что на этом остановимся,
хотя нам явно еще потребуются специальные функции для скрытия и показа
слоев. Имитация гиперссылокТеперь перейдем к разделу <BODY>. Прежде всего,
напишем заголовок, который не претерпит никаких изменений: <DIV CLASS="hdr" ID="hdrl">Фирма «Лентяй»</DIV> А вот сейчас нам нужно будет написать блок мнимых гиперссылок,
которые будут скрывать и показывать слои. Если помните, у нас для них
был определен класс rght: <DIV CLASS="rght"> Поскольку
каждая «гиперссылка» должна выполнять скрытие и показ слоев, а не загрузку
нового файла, тег <А> нам не потребуется, зато потре- буется
обработчик событий onClick. Пусть этот обработчик запускает функцию, которая
будет показывать нужный слой и скрывать остальные. Поскольку слоев у нас
немного, мы можем себе позволить на этом месте не очень напрягаться и написать
отдельную функцию для показа каждого из слоев: <DIV CLASS="lnk" onClick="showmain()">УСЛУГИ</DIV>
<DIV CLASS="lnk" onClick="showprices()">ЦЕНЫ</DIV> и т. д. Сами эти функции
мы напишем позже, а сейчас подумаем о том, чтобы по виду наши мнимые гиперссылки
выглядели, как настоящие. Если помните, на этой странице при наведении указателя
мыши на гиперссылку мы выделяли ее полужирным шрифтом (для этого был определен
псевдокласс A:hover). Давайте попробуем сделать то же самое с нашими мнимыми
гиперссылками, для чего определим для них обработчики событий onMouseOver и
onMouseOut, например, вот так: <DIV CLASS="lnk" onClick="showprices() " onMouseOver="this.style.fontWeight='bold';"
onMouseOut="this.style.fontWeight='normal';">ЦЕНЫ</DIV> Как видите, чтобы
не усложнять доступ к гиперссылке, мы осуществляем его с помощью ключевого слова
this. Однако у нас была еще одна задумка: выделить красным цветом ссылку на
текущий раздел (то есть тот, который в данный момент отображается на экране).
Хорошо бы это сохранить. Для этого нам придется одновременно с показом слоя
выделять красным цветом соответствующую ссылку внутри функции, а одновременно со
скрытием слоя менять ее цвет обратно на белый. Чтобы это было легче осуществить
придется сейчас присвоить всем мнимым гиперссылкам уникальные имена с помощью
атрибута ID=: <DIV CLASS="lnk" ID="pricelink" onClick="showprices()" onMouseOver="this.style.fontWeight='bold'
; " onMouseOut="this.style.fontWeight='normal';">ЦЕНЫ</DIV> Такой вид будут
иметь все мнимые гиперссылки. Однако, если помните, среди них имеются ссылки на
два еще не написанных раздела: «Форма заказа» и «История компании». При нажатии
на них мы будем выводить предупреждающее сообщение так же, как это делалось в
разделе 8.1. Однако здесь это будет сделать еще легче, так как не придется
использовать оператор return false для подавления действия тега
<А>: <DIV CLASS="lnk" onClick="alert ('Извините, этот раздел
еще не готов!\nПриходите позже!');" onMouseOver="this.style.fontWeight=
'bold';" onMouseOut="this.style.fontWeight='normal';"> ФОРМА ЗАКАЗА </DIV> Кроме того,
пользователь привык, что над гиперссылками изменяется вид указателя мыши. Чтобы
наши мнимые гиперссылки действовали так же, добавим им стилевое свойство cursor:
hand. Поскольку все они относятся к классу Ink, это стилевое свойство можно
добавить прямо в таблицу стилей: cursor: hand; text-align: center; } Управление отображением слоевТеперь нужно
написать код слоев. Все слои должны показываться в левой части экрана, то есть
относиться к классу lft. Для каждого из слоев необходимо задать уникальное имя,
чтобы можно было легко получить доступ к его свойствам из функции JavaScript.
Первый слой (раздел «Услуги») можно отобразить на экране
изначально: <DIV CLASS="lft" ID="main" STYLE="visibility: visible"> Далее мы просто пишем весь код основного раздела (список
услуг). Аналогично создадим второй слой: <DIV CLASS="lft" ID="guestbook" STYLE="visibility:
hidden"> Как видите, этот слой изначально не будет виден, поскольку
его свойство visibility имеет значение hidden. После этого тега мы просто
пишем весь текст формы отзыва, который мы уже рассматривали выше. И, наконец,
создадим еще один слой: <DIV CLASS="lft" ID="prices" STYLE="visibility: hidden"> Сюда запишем
код нашего интерактивного прайс-листа. Обратите внимание на то, что необходимые
функции мы уже вставили в раздел <HEAD>, так что все будет работать.
Правда, если доступ к элементам формы интерактивного прайс-листа осуществляется
не через метод document.all, а через document.forms, то придется обращение
document.forms[0] заменить на document.forms[1], поскольку на этой странице это
уже не первая, а вторая форма (в предыдущем слое «Книга отзывов» также
использовалась форма). Вообще говоря, чтобы не путаться в номерах (индексах)
форм лучше просто присваивать им уникальные имена: <FORM ID="pr"> и затем уже
обращаться к форме по имени, через метод document.forms.pr (вместо
document.forms[1]). Теперь нужно
написать функции для показа и скрытия слоев. В этом нет ничего сложного — нужно
просто присвоить значение visible или hidden свойству visibility нужного слоя.
Одновременно не забудем изменить цвет соответствующей мнимой
гиперссылки: Эта функция
отобразит слой main, одновременно выделив красным цветом ссылку на него, и
скроет слои prices и guestbook. Функции для отображения слоев prices и guestbook
будут выглядеть аналогично. Чтобы изначально выделить красным цветом ссылку на
раздел «Услуги», можно просто запустить функцию showmain() сразу после загрузки
страницы: <BODY onLoad="showmain();"> Дополнительное оформлениеСобственно
говоря, это все. Однако напоследок давайте еще немного украсим страницу,
заставив ее заголовок перемещаться случайным образом (но не «заезжать» при этом
на другие элементы). Для этого напишем специальную функцию flow(). Вспомним, что
изначально свойства left и top заголовка (координаты его верхнего левого угла)
имеют значения 50 и 10 соответственно. Попробуем изменять их в интервале от 0 до
100 для left и от 0 до 20 для top: var a=Math.floor(Math.random()*100); var b=Math.floor(Math.random()*20)
; document.all.hdrl.style.pixelLeft=a; document.all.hdrl.style.pixelTop=b; Поясним, что
метод Math.random генерирует случайные значения в интервале от 0 до 1. Умножая
это значение на 100, мы получаем случайное число в интервале от 0 до 100.
Округлив его в меньшую сторону методом Math.floor, мы присваиваем получившееся
значение свойству заголовка pixelLeft, то есть изменяем местоположение этого
заголовка. То же самое происходит в этой функции с вертикальной координатой
заголовка (свойством pixelTop). Однако написанная
функция лишь однократно изменяет расположение заголовка. Чтобы заставить
заголовок перемещаться случайным образом все время, нужно вызывать эту функцию
многократно. Для этого воспользуемся методом setlnterval: <BODY onLoad="set!nterval("flow()", 1000); showmain();"> Как видите,
использование метода setlnterval во многом аналогично использованию метода
setTimeout, однако setlnterval, в отличие от последнего, вызывает указанную
функцию не один раз, а многократно, через заданное количество миллисекунд (то
есть в нашем случае через каждую секунду). Таким образом, расположение заголовка случайным образом изменяется через каждую секунду. Теперь давайте посмотрим на текст получившейся страницы целиком.
Видимый результат всех этих манипуляций будет почти таким же, как и в разделе 8.1 (см., например, рис. 8.3). Однако пользоваться таким сайтом удобнее, так как не надо после нажатия на ссылку каждый раз ждать загрузки соответствующего раздела с сервера. |