
Ajax в действии
.pdf
Рис. 13.2. Последовательность действий программы чтения RSS-пент
Уникальность нашего приложения заключается в том, что оно не использует никакого серверного кода; мы только получаем XML-документы RSS, создаваемые другими Web-сайтами. Все приложение размещается на Webстранице, записанной в среде рабочего стола или загружаемой как часть нашего Web-сайта.
Прежде всего необходимо понять, на какие этапы разбивается разработка требуемого приложения. Мы разрабатываем программу чтения RSS-лент, которая настраивает слайд-шоу, использующее два слоя. Каждый слой будет содержать одну ленту, которая будет показываться заданный период времени, после чего будет проявляться вторая лента. Алгоритм действий данного приложения показан на рис. 13.2.
Процесс чтения лент состоит из нескольких этапов Первый этап — это загрузка нескольких выбранных лент. Для хранения информации, необходимой различным ист:очникам лент, мы будем применять общий массив. Кроме того, мы не будем использовать дополнительные элементы статей, приведенные в табл. 13.2.
После загрузки файлов нам придется создать упомянутый выше эффект перехода (постепенное проявление и затухание). В данном случае мы используем для этого классы CSS. Переключение между сообщениями и циклический показ сообщений будет реализован с помощью таймера.
Мы также создадим в приложении кнопки "Вперед", "Назад" и "Пауза". Кроме того, можно добавить возможность вставки дополнительных потоков из предлагаемого списка. А начнем мы с создания на стороне клиента формы и слоев.
13.2.2. HTML-структура без таблиц
Самой объемной частью данного проекта является представление. Для создания структуры в форме таблицы, содержащей заголовок, тело и нижний колонтитул, мы используем ряд элементов div и span. Результат, который мы собираемся получить, показан на рис. 13.3.

Рис. 13.3. Окончательный вид программы чтения RSS-лент
Для формирования структуры можно было бы использовать и таблицы, но такое решение было бы допустимым до начала эпохи CSS (см. главу 2). В настоящее время использование таблиц нежелательно, поскольку их визуализация требует больше времени, а изменять их сложнее, чем структуру на основе CSS. В листинге 13.1 показана разметка, на которой будет основываться структура нашей программы чтения XML-сообщений.
Листинг 13.1. Структура HTML-формы, используемой приложением
<form name="Forml">
<! — О Внешний элемент div —> <div id="divNewsHolder">
<! — © Элемент div заголовка —>
<div id="divNewsTitle"> < ! — © Счетчик лент —>
<span id="spanCount">Loading</span> < ! — О Название —>
Ajax News Viewer </div>
<! — © Контейнер для лент новостей —> <div id="divAd">
<! — 0 Слой первой ленты новостей —> <div id="divNewsl">
Loading Content...
</div>
< ! — О Нижний колонтитул структуры —> <div id="divNews2">
Loading Content...
</div>
</div> < i — 0 — >
<div id="divControls">
<! — © Кнопки действия —>
<i n p u t t y p e = " b u t t o n " name="btnPrev"

524 Часть IV. А/ах в примерах
Рис. 13.4. Элементы HTML без стилей CSS
i d = " b t n P r e v " value="<BACK" />
<i n p u t t y p e = " b u t t o n " name="btnPause"
id = " b t n P a u s e " value="PAUSE" />
<i n p u t t y p e = " b u t t o n " name=i "btnNext"
id = " b t n N e x t " value="NEXT>" /> <hr/>
< ! — © Дополнительный элемент лент —>
<s e l e c t name="ddlRSS">
</ s e l e c t >
<i n p u t t y p e = " b u t t o n " name="btnAdd"
value="Add Feed" /> </div>
</div>
</form>
Первым элементом div является divNewsHolder О — контейнер, используемый для задания общего размера окна, в котором будет отображаться результат выполнения приложения. Следующий элемент div — divNewsTi- t l e © — вмещает заголовок нашей структуры. Внутри этого элемента div мы добавляем элемент span ©, содержащий заполнитель-счетчик лент. Следующая строка текста О — это название нашего приложения. В данной строке мы можем написать все, что угодно.
Далее идет элемент divAd ©. Это строка представляет собой заполнитель, содержащий информацию о RSS-ленте, которую мы извлечем позже. В элемент divAd мы помещаем еще два элемента div, divNewsl © и divNews2 ©, которые используются для хранения информации RSS-ленты. Позже мы изменим свойства CSS данных элементов с помощью JavaScript, чтобы создать эффект затухания.
Строка нижнего колонтитула создается с помощью элемента div divCon- t r o l s ©. Она содержит средства навигации и функции управления лентой. В данный элемент div добавляются кнопки "Вперед", "Назад" и "Пауза" ©. Чтобы пользователь мог выбирать дополнительные XML-ленты, добавляются элемент формы выбора и еще одна кнопка ©. Таким образом, мы получаем каркас приложения, показанный на рис. 13.4.
Рис. 13.4 выглядит не очень привлекательно, поскольку мы еще не отформатировали элементы HTML, но с введением правил CSS это изменится. Изучая рис. 13.3, видим, что наши элементы div (divNewsl и divNews2) должны накладываться друг на друга, чтобы мы смогли правильно реализовать эффект затухания.

Глава 13 Создание приложений Ajax, не использующих сервер 525
13.2.3. Гибкое CSS-форматироеание
Без CSS наши Web-страницы выглядели бы так, как показано на рис. 13.4: серыми и неприглядными. Чтобы улучшить данный пример, мы применим к элементам правила стилевого оформления CSS. Стили позволяют легко редактировать свойства в будущем, не требуя редактирования HTML-файла. Первым элементом, для которого мы разработаем стиль, будет внешний контейнер div и строка заголовка.
Применение стиля к контейнеру и заголовку
Упомянутый ранее элемент divNewsHolder можно считать контейнером для нашего приложения. Он позволяет размещать программу чтения RSS-лент на странице и задавать ее ширину. Поскольку для представления остальных строк мы используем элементы div, они будут занимать 100% доступной им ширины страницы. Задавая ширину в контейнере, мы можем жестко задать размер остальных элементов, что облегчит их последующие обновления. Реализация сказанного с помощью CSS показана в листинге 13.2.
Листинг 13.2. Правила CSS для контейнера и заголовка
/ / О Элемент div контейнера #divNewsHolder{
width: бООрх;
border: 2px solid black; padding: Орх;
)
// © Элемент div заголовка #divNewsTitle{
font-size: 20px; height: 26px;
background-color: #BACCD9; // © Высота строки
J line-height: 26px;
//О Счетчик #spanCount{
//© Структура основана на "плавающих" элементах
float: right; font-size: 15рх; padding-right: 10px;
> •
Для определения стиля элементов формы вызываются идентификаторы этих элементов со знаком # О. Таким образом указывается, что стиль необходимо связать только с элементом div, имеющим идентификатор divNewsHolder. В данном случае для элемента divNewsHolder задаются ширина и граница, а область заполнения устанавливается равной 0.
Задав стиль контейнера, можно форматировать его первую строку. Д л я элемента divNewsTitle нам хотелось бы установить высоту, цвет фона и размер шрифта ©. Значение свойства line-height © задается равным высоте

Рис. 13.5. К элементам d i v контейнера и заголовка применены правила CSS
элемента div. Таким образом, мы гарантируем, что наша строка текста высотой 20 пикселей будет правильно вертикально центрирована в элементе div. Если не задавать высоту текста, он будет размещен возле верхней границы элемента div.
Последним этапом форматирования строки заголовка будет перемещение элемента spanCount О к правому краю заголовка {изначально он находится перед заголовком). Для этого используется свойство float ©, значение которого устанавливается равным right. Вследствие этого наш текст выравнивается по правому краю, независимо от ширины элемента-контейнера (причем на заголовок данное правило не влияет). Размер шрифта основного текста можно сделать немного меньше, чтобы он не так бросался в глаза, как заголовок. Свойство padding-right определяет смещение текста от правого края, чтобы он не соприкасался с границей контейнера. Теперь стилевое оформление контейнера и заголовка завершено; результат его применения показан на рис. 13.5.
На рис. 13.5 видно, что строка заголовка очень отличается от других строк, стиль которых мы еще не определили. Слово Loading располагается в правой части элемента div, а текст внутри элемента div центрирован по вертикали. Граница элемента div, представляющего контейнер приложения, окружает все остальные элементы.
Далее мы займемся стилевым оформлением оставшихся элементов div.
Стилевое оформление содержимого окна
Следующий этап — определение стиля среднего участка, или тела, нашего приложения (листинг 13.3). Раздел тела будет содержать отформатированную информацию RSS-ленты. Элементы div divNewsl и divNews2 наложатся друг на друга; это нужно для создания эффекта перехода. Для реализации этого эффекта мы будем так увеличивать прозрачность слоя, чтобы постепенно становился виден слой, расположенный под ним.
Листинг 13.3. Правила CSS для элементов div тела
//О Отформатировать divAd #divAd{
//© Задать ширину-
width: 100%;
//© Задать высоту height: 400рх;
//О Скрыть полосу прокрутки overflow: hidden;
//© Отформатировать границы border-top: 2px solid black;
Глава 13 Создание приложений Ajax, не использующих сервер 527
border-bottom: 2px solid black;
}
// © Задать стиль обоих элементов div новостей
#divNews1, #divNews2{
// в Задать ширину и высоту width: 100%;
height: 40Opx; background: #D9CCBA;
//О Задать относительное расположение position: relative;
//© Если необходимо, показать полосы прокрутки
overflow: auto;
// © Придвинуть элементы div к краю
left: Opx;
1
/ / О Разместить первый элемент d i v #divNewsl{top: Opx;}
// © Разместить второй элемент d i v #divNews2{top: -4Q0px;}
Прежде всего нам требуется определить стиль элемента divAd О, представляющего собой контейнер элементов span RSS-лент. Ширина © устанавливается равной 100%, а высота © — 400рх. Нам не нужно, чтобы в данной строке использовалась полоса прокрутки, поэтому значение свойства overflow О устанавливается равным hidden. Это означает, что если ширина какого-то элемента будет больше 400 пикселей, он будет частично не видим. Другие элементы div внутри данного контейнера позволяют использовать прокрутку, поэтому содержимое мы не потерям. После этого мы задаем стиль верхней и нижней границ © в виде черных линий шириной 2 пикселя. Боковые границы не требуются, поскольку для общего контейнера задана ненулевая границы. Если бы мы задали границу вокруг всей строки, ее ширина по бокам была бы равна 4 пикселям, а сверху и снизу — всего 2 пикселям, т.е. выглядела довольно несуразной.
Далее необходимо отформатировать два элемента div, вмещающих содержимое, — divNewsl и divNews2 ©. Их свойства можно задать одновременно, разделив их идентификаторы запятой. Значения ширины и высоты © задаются такими же, как у элемента div внешнего контейнера. Задание относительного (relative) положения элементов div © позволяет размещать их относительно родительского контейнера divAd, в отличие от абсолютного (absolute) размещения, привязанного к левому верхнему углу окна браузера. Свойство overflow элементов div © задается равным auto, что позволяет при необходимости отображать полосы прокрутки. Последний этап — установка левой позиции элементов © равной 0 пикселей, что позволяет выравнивать элементы div, чтобы между их краями не было промежутков.
Нам требуется, чтобы два элемента div, содержащих новости, располагались один поверх другого. Поскольку используется относительное позиционирование, с этими двумя элементами необходимо соотнести различные

Рис. 13.6. Применение правил CSS к элементам d i v тела
свойства положения. Поэтому вертикальное положение элемента divNewsl О устанавливается равным 0 пикселям. Таким образом, этот элемент будет прилипать к верхней границе родительского элемента div. Положение элемента divNews2 © устанавливается равным -400рх. Почему мы используем отрицательное значение? Дело в том, что, как показано на рис. 13.4 и 13.5, второй элемент div располагается ниже по странице, чем первый элемент div. Поскольку высоту контейнера мы установили равной 400 пикселям, элемент divNews2 необходимо поднять на эти 400 пикселей, чтобы он выровнялся по верху родительского элемента div (так же, как divNewsl). Обращаясь к рис. 13.6, мы видим, что, в отличие от рис. 13.5, два элемента div теперь накладываются друг на друга.
Поскольку два элемента div располагаются один поверх другого, мы видим только содержимое одного из них. В данном случае уровень прозрачности установлен равным 100%, поэтому содержимое нижнего контейнера не видно. К такой конфигурации мы должны прийти после завершения перехода, однако, прежде, чем мы рассмотрим этот вопрос, давайте закончим разработку стилей нашего приложения.
Настройка нижнего колонтитула
Последним блоком, для которого мы определим правила CSS, является нижний колонтитул. Для данного раздела мы установим цвет фона и стандартизуем элементы формы, чтобы структура раздела была более отчетливой. Для этого мы задаем цвета, размер шрифта и размер кнопок (листинг 13.4).
Листинг 13.4. Правила CSS для элемента d i v нижнего колонтитула .
// |
О |
Определить |
стиль |
элемента d i v нижнего колонтитула |
// |
© |
Задать цвет |
фона |
|
#divControls { |
|
|
||
|
b a c k g r o u n d - c o l o r : #BACCD9; |

Глава 13. Создание приложений Ajax, не использующих сервер 529
// © Центрировать текст text-align: center;
// О Добавить заполнение padding-top: 4рх;
padding-bottom: 4px;
}
//© Определить стиль элементов формы #divControls input{
//© Установить размер и цвета
width: lOOpx; background-color: #8C8C8C; color: #000000;
f o n t - s i z e : Юрх;
}
С элементом div нижнего колонтитула divControls мы соотносим такие правила CSS О, чтобы этот элемент согласовывался со строкой заголовка. Цвет фона © данного элемента выбран таким же, как у заголовка. Текст горизонтально выравнивается по центру элемента ©. Далее добавляется заполнение сверху и снизу О, чтобы содержимое не прилипало к границе. Добавлять границу к данному элементу div не обязательно, поскольку для средней строки определена верхняя граница, а три остальные границы определены для внешнего контейнера.
Последним этапом CSS-форматирования нижнего колонтитула будет применение стилей к элементам формы, чтобы они согласовывались с общим стилем приложения. Для обращения к элементам кнопок ©, расположенным в divControl, используется структура, сформированная следующим образом: имя элемента div, пробел и имя дескриптора. Это означает, что указанные свойства будут сопоставлены только с элементами, расположенными в данном дескрипторе div. Все остальные элементы страницы с таким же именем дескриптора этих свойств не получат.
Поскольку текст всех кнопок имеет разную длину, то свойство width © для кнопок задается так, что теперь все они будут одинаковой ширины, т.е. выглядеть более однородно. Мы изменили цвет фона, и теперь он не совпадает с принятым по умолчанию в системе пользователя. Кроме того, можно задать цвет текста и размер шрифта текста элемента. На рис. 13.7 показан окончательный вид нижнего колонтитула — теперь он лучше согласуется с внешним видом всего приложения.
На рис. 13.7 видны все свойства, соотнесенные с элементами div. Мы определили размеры, цвета, кегли, границы, заполнение и многое другое. Свойства CSS этих элементов можно настроить так, чтобы они соответствовали любой заданной теме Web-сайта или личным предпочтениям. Далее нам необходимо получить текст для нашего RSS-клиента!

530 Часть IV Ajaxe примерах
Рис. 13.7. Применение правил CSS к нижнему колонтитулу
13.3.Загрузка RSS-лент
Вданном примере мы будем загружать файлы из нескольких лент. Для этого будет задействован объект ContentLoader (как и во всех остальных примерах книги). В первой версии разрабатываемого приложения просмотра RSS-лент мы используем ряд глобальных переменных.
13.3.1. Глобальный уровень
Глобальные переменные позволяют легко настраивать сценарий, чтобы нам не приходилось менять функциональные возможности внутри циклов for и таймеров. Возможность настройки содержимого глобальных переменных позволит вносить глобальные изменения в сценарий и осуществлять связь различных функций. Сейчас нам удобнее использовать именно глобальные, а не локальные переменные, поскольку они "открыты" для всех функций и можно не думать о возможности передачи информации из одной функции в другую. Позже в данной главе мы реструктуризируем сценарий и представим решение без использования глобальных переменных; сейчас же они просто облегчают нам разработку.
Одним из недостатков JavaScript является отсутствие типов переменных Для констант, поэтому мы имитируем их с помощью глобальных переменных. Однако следует помнить, что значения глобальных переменных могут перезаписываться, поэтому использовать их следует очень осторожно. Переменные, приведенные в листинге 13.5, в процессе работы нашего приложения никак меняться не будут.
Глава 13 Создание приложений Ajax, не использующих с&рвер 53"!
Листинг 13.5. Глобальные переменные с постоянным значением
var flipLength = 5000; var timeColor = 100; var strErrors = "<hr/>Error List: <br/>" var arrayRSSFeeds = new Array(
"http://radio.javaranch.com/news/rss.xml",
"http://radio.3avaranch.com/pascarell0/rss.xml",
"http://radio.]avaranch.com/bear/rss.xml",
"http://radio.3avaranch.c0m/lasse/rss.xml");
В листинге 13.5 мы определяем глобальные переменные, задающие функционирование нашего приложения. Первая глобальная переменная, f l i - pLength, определяет, сколько миллисекунд будет отображаться текущее сообщение до того, как оно заменится следующим. В данном случае время, проходящее между сменой сообщений, составляет 5000 миллисекунд. Следующая переменная-таймер — timeColor — задает время в миллисекундах между этапами "раскрашивания" нашего сценария. Чем больше ее значение, тем дольше переход.
Далее определяется глобальная переменная strErrors. Здесь формируется заголовок сообщений об ошибках, возникающих в процессе загрузки Стиль данного сообщения можно изменить; кроме того, с ним можно связать параметры стиля. Последняя глобальная переменная, влияющая на выполнение сценария, представляет собой массив arrayRSSFeeds. В данный массив мы добавляем URL лент RSS, которые нас интересуют. В данном случае мы обращаемся к четырем различным лентам RSS из радиоблогов JavaRanch.com.
Следующий набор глобальных переменных, представленный в листинге 13.6, используется для передачи данных между отдельными функциями Эти переменные хранят состояние приложения чтения RSS-лент Их значения изменяются согласно выполняемому действию.
Листинг 13.6. Глобальные переменные, содержащие информацию о состоянии
var currentMessage =» 0; |
|
var layerFront = 2; |
|
var timerSwitch; |
|
var bPaused = false; |
|
var arrayMessage = new Arrayt); |
|
var intLoadFile = 0; |
|
var bLoadedOnce = false; |
^ — |
Первая глобальная переменная, значение которой задается в листинге 13.6, — currentMessage. Она отслеживает сообщение, просматриваемое в текущий момент. В каком-то смысле ее можно считать счетчиком, который обнуляется при достижении максимального числа записей. Следующая глобальная переменная layerFront содержит состояние наших слоев. Разрабатывая структуру RSS-клиента, мы наложили друг на друга два слоя. Состояние этих слоев отслеживается в переменной layerFront.