HTML: Популярный самоучитель
Шрифт:
В первом примере реализуется перемещение изображений«шариков» внутри рамки (элемент DIV). Шарики имеют случайные первоначальные скорости и направления движения. Кроме того, при достижении стенок (рамки элемента DIV) они упруго он них отталкиваются. Страница примера выглядит так, как показано на рис. 13.4.
Рис. 13.4. Перемещение «шариков» внутри элемента DIV
Ниже приведен текст HTML-документа, который показан на рис. 13.4 (пример 13.11).
<!DOCTYPE HTML PUBLIC «-//W3C//DTD HTML 4.01 Frameset//EN»
"http://www.w3.org/TR/html4/frameset.dtd">
<HTML>
<HEAD>
<TITLE>Страница с анимацией</TITLE>
<STYLE type = "text/css">
.ball {position: absolute}
.ballarea {border-style: solid; border-width:1px;
position: absolute; background-color: white}
</STYLE>
</HEAD>
<BODY>
<DIV class = "ballarea" id = "area">
<!–Изображения-шарики–>
<IMG src = "balls/ball1.bmp" class = "ball" id = "ball1">
<IMG src = "balls/ball2.bmp" class = "ball" id = "ball2">
<IMG src = "balls/ball3.bmp" class = "ball" id = "ball3">
<IMG src = "balls/ball4.bmp" class = "ball" id = "ball4">
<IMG src = "balls/ball5.bmp" class = "ball" id = "ball5">
<SCRIPT type = "text/javascript">
//Позиционируем
area.style.left = area.style.top = "10mm";
area.style.width = area.style.height = 200;
//Установим размер изображений-шариков ball1.style.pixelWidth = ball1.style.pixelHeight = 16;
ball2.style.pixelWidth = ball2.style.pixelHeight = 16;
ball3.style.pixelWidth = ball3.style.pixelHeight = 16;
ball4.style.pixelWidth = ball4.style.pixelHeight = 16;
ball5.style.pixelWidth = ball5.style.pixelHeight = 16;
</SCRIPT>
</DIV>
<SCRIPT type = "text/javascript" src = "balls.js"></SCRIPT>
</BODY>
</HTML>
Здесь предполагается использование пяти изображений из папки balls. Как видно из примера, чтобы сценарий нормально работал с координатами и размером изображений, соответствующие свойства пришлось установить не в CSS, а опять же с помощью сценария.
Во внешний файл вынесен сценарий, отвечающий за перемещение изображений (файл balls.js). Cодержимое файла balls.js выглядит следующим образом (пример 13.12).
//Массив со ссылками на объекты-изображения шариков var balls = [ball1, ball2, ball3, ball4, ball5];
//Массивы скоростей по горизонтали и вертикали (от –10 до 10)
var xSpeed = [rand(–10,10), rand(–10,10), rand(–10,10),
rand(–10,10), rand(–10,10)];
var ySpeed = [rand(–10,10), rand(–10,10), rand(–10,10),
rand(–10,10), rand(–10,10)];
//Минимальные значения координат изображений var minX = ball1.style.pixelLeft;
var minY = ball1.style.pixelTop;
//Максимальные значения координат изображений var maxX = area.style.pixelWidth + minX – balls[0].style.pixelWidth;
var maxY = area.style.pixelHeight + minY – balls[0].style.pixelHeight;
//Назначаем функцию обновления изображения, вызываемую по таймеру window.setInterval(redraw, 100);
//Функция генерации случайных значений function rand(min, max){
return Math.random*(max–min)+min;
}
//Функция обновления координат и перерисовки изображений function redraw{
var i, newX, newY;
for (i=0; i<balls.length; i++){
//Вычисляем новое положение шарика newX = balls[i].style.pixelLeft + xSpeed[i];
newY = balls[i].style.pixelTop + ySpeed[i];
//Проверка столкновения с границами if (newX > maxX){
newX = maxX;
xSpeed[i] = –xSpeed[i];
}
else if (newX < minX){
newX = minX;
xSpeed[i] = –xSpeed[i];
}
if (newY > maxY){
newY = maxY;
ySpeed[i] = –ySpeed[i];
}
else if (newY < minY){
newY = minY;
ySpeed[i] = –ySpeed[i];
}
//Наконец, перемещаем изображение balls[i].style.pixelLeft = newX;
balls[i].style.pixelTop = newY;
}
}
В следующем примере рассматривается сценарий, позволяющий случайным образом изменять цвет текста, для которого задан определенный стилевой класс. Стилевой класс в примере имеет название colored. Пример разбит на две части: собственно сценарий (файл coloredtext.js) и HTML-документ, использующий возможности этого сценария.
Для начала рассмотрим сам сценарий, код которого приведен ниже (пример 13.13).
//Поиск всех элементов, имеющих класс «colored»
var i, j = 0;
var elements = [];
for (i=0; i<document.all.length; i++){
if (document.all(i).className == "colored"){
elements[j] = document.all(i);
j++;
}
}
//RGB-составляющие цвета текста var R = 0, G = 0, B = 0; //По умолчанию цвет черный
//Назначаем функцию перерисовки window.setInterval(redraw, 50);
//Функция генерации случайных значений function rand(min, max){
return Math.random*(max–min)+min;
}
function redraw{
//Вычисляем новые значения составляющих цвета
R += rand(–8, 8);
R = (R>=0) ? R : 0;
R = (R<=255) ? R : 255;
G += rand(–8, 8);
G = (G>=0) ? G : 0;
G = (G<=255) ? G : 255;
B += rand(–8, 8);
B = (B>=0) ? B : 0;
B = (B<=255) ? B : 255;
//Установка нового цвета для всех элементов for (i=0; i<elements.length; i++){
elements[i].style.color =
"rgb(" + R + "," + G + "," + B + ")";
}
}
Этот сценарий работает следующим образом. После загрузки содержимого документа (для этого файл должен подключаться к документу перед закрывающим тегом </BODY>) производится просмотр всей коллекции all документа, и в массив elements помещаются ссылки на все элементы, имеющие стилевой класс colored. Кроме обозначения элементов, цвет которых нужно изменять, этот стилевой класс больше ни для чего не используется.
Изменение цвета в примере осуществляется по таймеру. Значения RGB-составляющих цвета случайным образом изменяются на небольшие значения, что обеспечивает эффект этакого плавного перехода цвета. Еще следует отметить, что цвет всех отобранных элементов всегда одинаков. Это сделано для упрощения программы.
В примере 13.14 показано, как используется рассматриваемый сценарий.
<!DOCTYPE HTML PUBLIC «-//W3C//DTD HTML 4.01 Frameset//EN»
"http://www.w3.org/TR/html4/frameset.dtd">
<HTML>
<HEAD>
<TITLE>Разноцветный текст</TITLE>
<STYLE type = "text/css">
.colored {}
</STYLE>
</HEAD>
<BODY>
<H1>Обычный заголовок</H1>
<H1 class = "colored">Разноцветный заголовок</H1>
<P class>Обычный текст
<P class = "colored">Разноцветный текст
<SCRIPT type = "text/javascript" src = "coloredtext.js"></SCRIPT>
</BODY>
</HTML>
Теперь создадим усовершенствованный вариант рассмотренного ранее меню. Сейчас это будет не просто набор пунктов, все время находящийся на странице, а настоящее меню, похожее на то, которое имеют многие Windows-приложения.
Пример реализован следующим образом: вверху окна организуется строка меню, в которой присутствуют два пункта, открывающих два различных меню. Первое меню выглядит так, как показано на рис. 13.5.
Рис. 13.5. Открыто первое меню
Второе меню, вызываемое при выборе второго пункта в строке меню, показано на рис. 13.6.
Рис. 13.6. Открыто второе меню
Как видно, оба меню появляются под соответствующими пунктами строки меню. Теперь рассмотрим, как реализован этот пример, а также какие существуют направления усовершенствования этого примера. Пример разбит на две части: HTML-документ и сценарий (файл popup_menu.js). Сначала разберем текст HTML-документа (пример 13.15).
<!DOCTYPE HTML PUBLIC «-//W3C//DTD HTML 4.01 Frameset//EN»>
<HTML>
<HEAD>
<TITLE>Страница
с меню</TITLE><STYLE type = "text/css">
.item {background-color: rgb(170, 170, 170)}
.selected {background-color: magenta}
.menu {border-style: ridge; visibility: visible; position: absolute}
.hidden {display: none}
.menu_line {border-style: solid; border-width: 1px;
background-color: rgb(170,170,170); width:100%}
</STYLE>
<SCRIPT src = "popup_menu.js" type = "text/javascript"></SCRIPT>
</HEAD>
<BODY>
<!–Создаем первое меню (изначально оно скрывается)–>
<TABLE id = "menu1" class = "hidden">
<!–Первый пункт меню–>
<TR id = "menu1_item1" class = "item" onClick = "menu1_item1_click"
onMouseOver = "menu1_item1.className = 'selected'"
onMouseOut = "menu1_item1.className = 'item'">
<TD><IMG src = "icons/1.jpg"><TD>Первый пункт меню
<!–Второй пункт меню–>
<TR id = "menu1_item2" class = "item" onClick = "menu1_item2_click"
onMouseOver = "menu1_item2.className = 'selected'"
onMouseOut = "menu1_item2.className = 'item'">
<TD><IMG src = "icons/2.jpg"><TD>Второй пункт меню
<!–Третий пункт меню–>
<TR id = "menu1_item3" class = "item" onClick = "menu1_item3_click"
onMouseOver = "menu1_item3.className = 'selected'"
onMouseOut = "menu1_item3.className = 'item'">
<TD><IMG src = "icons/3.jpg"><TD>Третий пункт меню
<!–Четвертый пункт меню–>
<TR id = "menu1_item4" class = "item" onClick = "menu1_item4_click"
onMouseOver = "menu1_item4.className = 'selected'"
onMouseOut = "menu1_item4.className = 'item'">
<TD><IMG src = "icons/4.jpg"><TD>Четвертый пункт меню
<!–Пятый пункт меню–>
<TR id = "menu1_item5" class = "item" onClick = "menu1_item5_click"
onMouseOver = "menu1_item5.className = 'selected'"
onMouseOut = "menu1_item5.className = 'item'">
<TD><IMG src = "icons/5.jpg"><TD>Пятый пункт меню
</TABLE>
<!–Создаем второе меню (изначально оно также скрывается)–>
<TABLE id = "menu2" class = "hidden">
<!–Первый пункт меню–>
<TR id = "menu2_item1" class = "item" onClick = "menu2_item1_click"
onMouseOver = "menu2_item1.className = 'selected'"
onMouseOut = "menu2_item1.className = 'item'">
<TD><IMG src = "balls/ball1.bmp"><TD>Первый пункт меню
<!–Второй пункт меню–>
<TR id = "menu2_item2" class = "item" onClick = "menu2_item2_click"
onMouseOver = "menu2_item2.className = 'selected'"
onMouseOut = "menu2_item2.className = 'item'">
<TD><IMG src = "balls/ball2.bmp"><TD>Второй пункт меню
<!–Третий пункт меню–>
<TR id = "menu2_item3" class = "item" onClick = "menu2_item3_click"
onMouseOver = "menu2_item3.className = 'selected'"
onMouseOut = "menu2_item3.className = 'item'">
<TD><IMG src = "balls/ball3.bmp"><TD>Третий пункт меню
</TABLE>
<!–Вверху страницы организуется строка меню–>
<TABLE id = "main_menu1" class = "menu_line">
<COL span = "2" width = "150">
<COL width = "*">
<TR>
<TD class = "item" id = "main_item1"
onClick = "show_menu(menu1, main_menu1, main_item1)"
onMouseOver = "main_item1.className = 'selected'"
onMouseOut = "main_item1.className = 'item'">Показать меню1
<TD class = "item" id = "main_item2"
onClick = "show_menu(menu2, main_menu1, main_item2)"
onMouseOver = "main_item2.className = 'selected'"
onMouseOut = "main_item2.className = 'item'">Показать меню2
<TD><!-Пустая ячейка, просто занимает место–>
</TABLE> <!–Далее идет остальное содержимое страницы–>
Текст страницы...
</BODY>
</HTML>
Хотя документ практически не содержит текста, являющегося обычным содержимым страницы (ведь мы рассматриваем не наполнение страницы текстов, а меню), он все равно получился довольно объемным. Больше всего места в документе примера 13.5 занимают описания двух меню. Описание первого меню практически не отличается от рассмотренного ранее в примере 13.6. Второе же меню, обозначенное как menu2, создано по такому же шаблону.
В таблицу стилей пришлось добавить новый стиль menu_line. После этого очень просто создавать любое количество строк меню на странице. При создании строки меню основной работой является настройка пунктов, которые будут открывать нужные меню (см. определение пунктов в таблице с id, равным main_menu1 в примере 13.5).
При выборе пунктов из строки меню происходит вызов одной и той же функции сценария. Этой функции в качестве параметров передается ссылка на меню, которое нужно открыть, а также ссылки на строку меню и ссылка на пункт, к которому относится показываемое меню. При рассмотрении сценария станет ясно, зачем это нужно.
Ниже приводится текст сценария из файла popup_menu.js (пример 13.16).
/*
Функция показывает заданное всплывающее меню под заданным главным пунктом заданного меню
*/
var lastMenu = null; //Предыдущее показанное меню function show_menu(menu, main_menu, item){
if (menu.className == "menu"){
//Закрываем открытое меню hide_menu;
return;
}
if (lastMenu != null)
//Скрываем прошлое меню hide_menu;
//Определяем положение меню menu.className = "menu";
menu.style.top = main_menu.offsetTop + main_menu.clientHeight;
menu.style.left = main_menu.offsetLeft + item.offsetLeft;
lastMenu = menu;
}
//Функция скрывает меню, открытое ранее function hide_menu{
lastMenu.className = "hidden";
lastMenu = null;
}
/*
Далее содержатся функции-обработчики для каждого пункта меню "menu1"
*/
function menu1_item1_click{
hide_menu;
alert("Вы выбрали первый пункт в меню1");
//Другие действия...
}
function menu1_item2_click{
hide_menu;
alert("Вы выбрали второй пункт в меню1");
//Другие действия...
}
function menu1_item3_click{
hide_menu;
alert("Вы выбрали третий пункт в меню1");
//Другие действия...
}
function menu1_item4_click{
hide_menu;
alert("Вы выбрали четвертый пункт в меню1");
//Другие действия...
}
function menu1_item5_click{
hide_menu;
alert("Вы выбрали пятый пункт в меню1");
//Другие действия...
}
/*
Далее содержатся функции-обработчики для каждого пункта меню "menu2"
*/
function menu2_item1_click{
hide_menu;
alert("Вы выбрали первый пункт в меню2");
//Другие действия...
}
function menu2_item2_click{
hide_menu;
alert("Вы выбрали второй пункт в меню2");
//Другие действия...
}
function menu2_item3_click{
hide_menu;
alert("Вы выбрали третий пункт в меню2");
//Другие действия...
}
Первая функция приведенного в примере 13.16 сценария отвечает за правильное отображение меню. Первый параметр является ссылкой на показываемое меню (таблица в HTML-документе).
Второй и третий параметры используются для корректного позиционирования показываемого меню. Перед тем как будет показано новое меню, скрывается то, которое было показано ранее (если оно имеется). Для этого ссылка на отображаемое меню сохраняется в глобальной переменной lastMenu.
Если пользователь открыл меню, но потом передумал выбирать какой-либо пункт, он должен иметь возможность закрыть меню. В рассматриваемом примере для закрытия меню пользователь должен повторно выбрать тот же самый пункт строки меню.