Данная глава предназначена для того, чтобы познакомить вас с применением сценариев для создания динамических HTML‑документов на примере языка программирования JavaScript.
13.1. Основы использования сценариев в HTML-документе
Помещение сценария в документ
Для помещения сценария РІ документ достаточно использовать HTML‑элемент SCRIPT. Ртот элемент задается парными тегами и имеет следующие атрибуты:
• src – URI файла, в котором записан код внешнего сценария;
• type – задает тип содержимого элемента SCRIPT или файла, определенного атрибутом src, принимает значения вида text/язык_сценария (например, text/javascript, text/vbscript);
• language – задает язык сценария (например, javascript или vbscript); при использовании атрибута type этот атрибут излишен.
Рлемент SCRIPT может появляться как РІ заголовке, так Рё РІ теле документа произвольное количество раз. Рассмотрим пример внедрения РІ документ простейшего сценария РЅР° JavaScript (язык рассмотрим чуть позже) (пример 13.1).
Пример 13.1. Сценарий в HTML-документе
<!DOCTYPE HTML PUBLIC В«-//W3C//DTD HTML 4.01 Frameset//ENВ»
"http://www.w3.org/TR/html4/frameset.dtd">
<HTML>
<HEAD>
<TITLE>Простейшая страница со сценарием</TITLE>
</HEAD>
<BODY>
<SCRIPT type = "text/javascript">
var date = new Date;
if (date.getHours() < 8 || date.getHours() > 22)
document.write("<P align = right><FONT color = black><I>Не спится?</I></FONT></P>");
else if (date.getHours() < 11)
document.write ("<P align = right><FONT color = blue><I>Доброе утро </I></FONT></P>");
else if (date.getHours() < 17)
document.write ("<P align = right><FONT color = red><I>Добрый день</I></FONT></P>");
else document.write ("<P align = right><FONT color = green><I>Добрый вечер</I></FONT></P>");
</SCRIPT>
<H1>Страница, содержащая сценарий</H1>
<P>Прочий текст страницы...
</HTML>
Участки кода между , начинающиеся с document.write(), должны быть записаны в одну строку, иначе пример работать не будет. Что же делает сценарий в приведенном примере? Да ничего особенного, просто при загрузке страницы печатает в правом верхнем углу приветствие, цвет и текст которого зависят от времени суток.
Стоит сказать несколько слов Рѕ еще РѕРґРЅРѕРј HTML‑элементе, имеющем отношение Рє сценариям, – это NOSCRIPT. Ртот HTML‑элемент задается парными тегами и полезен, РєРѕРіРґР° автор документа хочет подстраховаться РЅР° случай, если его документ будет открыт РІ браузере, РЅРµ поддерживающем сценарии вообще или РЅРµ поддерживающем сценарии РЅР° используемом языке программирования. Ртак, если сценарий РЅРµ может быть выполнен, то браузер отобразит содержимое элемента NOSCRIPT (РІ нем может быть, например, гиперссылка РЅР° версию документа, РЅРµ использующую сценарии).
Скрытие сценария
Рассмотрим прием, который часто применяется для того, чтобы браузер, вообще «не знающий» HTML‑элемента SCRIPT, РЅРµ показал пользователю текст сценария. Рто может случиться, если сценарий помещен РІ тело документа.
Для предотвращения возникновения такой ситуации текст сценария помещают в HTML‑комментарий следующим образом:
<SCRIPT type = В«text/javascriptВ»>
<!–
//Текст программы, помещенной здесь, пользователь не увидит случайно
–>
</SCRIPT>
Браузеры, поддерживающие элемент SCRIPT, должны проигнорировать HTML‑комментарий внутри этого элемента (хотя некоторые версии браузера Netscape Navigator не воспринимали сценарий, заключенный в комментарий HTML).
Другим вариантом скрытия, который должен точно работать, является помещение сценария во внешнем файле и подключение его при помощи атрибута src элемента SCRIPT.
13.2. Рсполнение сценария
Теперь рассмотрим, как организовать выполнение написанных Рё внедренных РІ документ сценариев. Ртак, сценарий может исполняться РІ РґРІСѓС… случаях: РїСЂРё загрузке документа Рё РїСЂРё возникновении события (Р° также РїСЂРё вызове его интерпретатором, например, РїРѕ таймеру, РЅРѕ это рассмотрим РѕСЃРѕР±Рѕ).
Рсполнение РїСЂРё загрузке документа
Рнтерпретатор браузера выполняет операторы языка JavaScript, записанные РІРЅРµ тела какой‑либо функции, только РѕРґРёРЅ раз РїРѕ мере загрузке документа. Причем положение HTML‑элемента SCRIPT СЃ текстом сценария определяет момент времени, РІ который сценарий будет выполняться. Так, сценарий РІ примере 13.1 выполнялся именно РґРѕ того, как было загружено остальное содержимое документа, поэтому выведенный РёРј текст Рё появился раньше РѕСЃРЅРѕРІРЅРѕРіРѕ содержимого документа.
Чтобы при загрузке HTML‑документа выполнялась какая‑либо функция, в нужном месте сценария должен быть записан вызов функции. Так, пример 13.1 можно переписать следующим образом (пример 13.2 сокращен).
Пример 13.2. Вызов функции при загрузке документа
...
<BODY>
<SCRIPT type = "text/javascript">
function greeting(){
//Те же действия, что и в примере 13.1...
}
//Вызов функции greeting();
</SCRIPT>
<H1>Страница, содержащая сценарий</H1>
<P>Прочий текст страницы...
</HTML>
Если бы в коде сценария не было явного вызова функции greeting(), то на странице не появилось бы приветствие.
Реакция на события
Сценарий может быть также запущен браузером при возникновении на странице какого‑либо события, с которым сопоставлен сценарий, – обработчика события. Генерацию событий могут вызывать различные действия пользователя: щелчок кнопкой мыши на элементе страницы, наведение указателя мыши на элемент и др.
Для назначения обработчиков события используются атрибуты HTML‑элементов, приведенные в табл. 13.1.
Таблица 13.1. Атрибуты для назначения обработчиков событий
Значениями приведенных в таблице атрибутов могут быть фрагменты кода сценариев, например:
<P onClick = «alert('Не давите на меня!!!')»>Текст абзаца
<P onClick = "
{
//Аккуратно оформленный блок кода, ведь строки HTML-разметки можно
//безнаказанно разрывать
alert('Лучше нажимайте на соседний абзац.');
}">Текст абзаца
Обратите внимание, что поскольку текст обработчика помещается в двойные кавычки, то сами кавычки в тексте сценария использовать не следует. Обычной практикой является создание функций‑обработчиков события (обычной функции JavaScript) вместо записи действий по обработке события прямо в теге элемента. В таком случае в атрибут onСобытие записывается код вызова функции‑обработчика.
События, возникающие в дочерних элементах, передаются вверх по иерархии родительским элементам. Так, например, если над текстом элемента B в приведенном ниже примере произойдет щелчок кнопкой мыши, то событие получит сначала элемент B, потом элемент P, а затем и элемент BODY:
<BODY onClick = В«body_click()В»>
<P onClick = "p_click()">Обычный текст
<B onClick = "b_click()">полужирный текст</B>
13.3. Объектная модель документа
Чтобы можно было успешно применить полученные значения по программированию на JavaScript, нужно рассмотреть еще один специфический момент – это то, как сценарии могут воздействовать на HTML‑документ. Для этого необходимо изучить технологию представления HTML‑документа в виде совокупности объектов – объектную модель документа (DOM, Document Object Model). DOM включает не только объекты, из которых состоит документ, но и объекты, позволяющие получать различную информацию о браузере, системе (в частности, о видеосистеме компьютера), работать с окнами и многое другое.
Объект document
Для программиста РЅР° JavaScript HTML‑документ представляется РІ РІРёРґРµ объекта document. Ртот глобальный объект существует РІ единичном экземпляре. Рћ создании объекта document заботится интерпретатор.
Свойства и методы объекта document
Ртак, объект document предоставляет СЂСЏРґ свойств Рё методов, позволяющих осуществлять практически любые манипуляции СЃ HTML‑документом. Основные свойства объекта document приведены РІ табл. 13.2.
Таблица 13.2. Свойства объекта document
Свойства, отвечающие за цветовое оформление, хранят целочисленные значения. Другие свойства, кроме возвращающих коллекции, хранят строки. Особо следует рассмотреть свойства, которые возвращают коллекции: all, anchors, forms, frames, images и links. В этих коллекциях находятся объекты, описывающие соответствующие элементы HTML‑документа.
Коллекции – это тоже объекты, во многом похожие на массивы. Однако коллекции предоставляют доступ к своим элементам c помощью метода item(). Причем доступ может осуществляться как по номеру элемента в коллекции, так и по его имени (задается атрибутом id или name элемента). Нумерация элементов в коллекциях начинается с нуля. Кроме того, для коллекций предусмотрено свойство length, хранящее количество элементов в коллекции.
В качестве примера рассмотрим, как получить доступ к элементам следующего HTML‑документа (пример 13.3).
Пример 13.3. HTML-документ, к элементам которого нужно получить доступ
<HTML>
<HEAD>
<TITLE>Заголовок документа</TITLE>
</HEAD>
<BODY>
<H1 id = "main_part">Главный заголовок документа</H1>
<P id = "par1">Текст документа...
</BODY>
</HTML>
Если осуществлять доступ к элементам документа при помощи коллекции all с использованием номеров, то доступ ко всем элементам документа будет выглядеть следующим образом:
var elements = []; //Массив, в который скопируем ссылки на объекты страницы
var i;
for (i=0; i<document.all.length; i++)
elements[i] = document.all(i);
В примере 13.3 в коллекции all содержится шесть элементов, поэтому массив elements после выполнения приведенного фрагмента программы должен содержать шесть элементов. Обратите внимание, как осуществляется доступ к элементам коллекции all: имя метода item() можно опускать.
Если бы доступ к элементам коллекции осуществлялся по имени HTML‑элементов, то можно было бы получить объекты, описывающие заголовок и абзац, следующим образом:
var h = document.all(В«main_partВ»);
var p = document.all("par1");
Возможно также прямое обращение к поименованным элементам документа. При использовании этого способа предыдущий фрагмент программы будет выглядеть следующим образом:
var h = main_part;
var p = par1;
Кроме достаточно богатого набора свойств, можно пользоваться методом write() объекта document для добавления к HTML‑документу любого текста прямо из сценария. Метод write() принимает строку, в которой может содержаться любое HTML‑форматирование, например:
document.write('<H1 id = «part2»>Текст, напечатанный сценарием</H1>')
При выполнении этого фрагмента программы не только появляется текст заголовка в окне браузера, но и создается объект с именем part2, к которому можно получить доступ с использованием той же коллекции all.
Рспользование методов open(URI_документа) Рё close() объекта document позволяет открывать новые HTML‑документы Рё закрывать РѕРєРЅРѕ браузера СЃ текущим документом, например:
open(«13.1.html») //Открываем пример 13.1 в новом окне
close(); //Пытаемся закрыть текущий документ
Управление элементами документа
Ртак, выше рассмотрено, как можно получить доступ Рє объектам, описывающим HTML‑элементы документа. Теперь же рассмотрим, какие общие действия можно производить СЃ полученными объектами.
Свойства, которые доступны для большинства элементов документа, приведены в табл. 13.3.
Таблица 13.3. Основные свойства элементов документа
В табл. 13.4 приводятся основные методы, которые можно использовать для манипулирования большинством элементов документа.
Таблица 13.4. Основные методы элементов документа
С использованием приведенных в таблицах свойств и методов можно осуществлять практически любые манипуляции с документом, показываемым в окне браузера. Сейчас дополнительно будут рассмотрены некоторые особенности доступа к элементам таблиц: доступ к строкам и ячейкам.
Объекты, описывающие таблицы, поддерживают внутреннюю коллекцию rows, СЃ помощью которой организовывается доступ Рє отдельным строкам таблицы. Рти объекты поддерживают также методы insertRow(номер) Рё deleteRow(номер), которые принимают РІ качестве параметра номер строки Рё позволяют вставить или удалить строку таблицы. Если метод insertRow() вызвать без параметра, то строка будет добавлена РІ конец таблицы. РџСЂРё успешном добавлении строки метод insertRow возвращает ссылку РЅР° объект, описывающий созданную строку.
Каждым элементом коллекции rows является объект, одним из свойств которого является коллекция cells, содержащая объекты, управляющие ячейками таблицы. Каждый элемент коллекции cells позволяет оперировать конкретными ячейками таблицы. Добавление ячеек в строку таблицы можно осуществлять при помощи метода insertCell(номер) объектов коллекции rows. Удалять же ячейки можно, используя метод deleteCell(номер) объектов той же коллекции.
Наконец, как завершающий этап знакомства с объектом document создадим несколько страниц, использующих его возможности.
Страница следующего примера будет представлять СЃРѕР±РѕР№ своеобразный каталог изображений. Рзображения вместе СЃ текстом, описывающим РёС…, Р±СѓРґСѓС‚ помещены РІ таблице. РџСЂРё этом помещение Рё удаление данных должно выполняться интерактивно (то есть этим управляет пользователь). Внешний РІРёРґ страницы примера приведен РЅР° СЂРёСЃ. 13.1.
Р РёСЃ. 13.1. Рзменяемая страница (каталог изображений)
При реализации примера код сценария и HTML‑код страницы расположены в отдельных файлах. Файл документа может иметь произвольное имя. Он выглядит следующим образом (пример 13.4).
Пример 13.4. Файл HTML-документа
<!DOCTYPE HTML PUBLIC В«-//W3C//DTD HTML 4.01 Transitional//ENВ»>
<HTML>
<HEAD>
<TITLE>Пример модифицирования таблицы сценарием</TITLE>
<SCRIPT type = "text/javascript" src = "script_13_4.js"></SCRIPT>
</HEAD>
<BODY>
<FIELDSET>
<LEGEND>Новое изображение</LEGEND>
РљРѕРґ: <INPUT name = "txtCode" maxlength = "4" size = "5">
Описание: <INPUT name = "txtName" maxlength = "500">
<BR>Путь к изображению: <INPUT type = "file" name = "txtFile">
<BR><INPUT type = "button" value = "Добавить рисунок"
onClick = "add_image(txtCode.value, txtName.value, txtFile.value)">
<INPUT type = "button" value = "Удалить рисунок..."
onClick = "delete_image()">
</FIELDSET>
<P>
<TABLE width = "100%" border>
<!–Определения столбцов таблицы–>
<COL width = "60">
<COL>
<COL width = "130">
<THEAD>
<TR><TH>Код<TH>Описание<TH>Просмотр
</THEAD>
<TBODY id = "mytable">
<!–Сюда сценарий вставляет записи–>
</TBODY>
</TABLE>
</BODY>
</HTML>
Р’ приведенном примере обратите внимание РЅР° элемент TBODY таблицы. РџСЂРёСЃРІРѕРёРІ ему РёРјСЏ, РІС‹ можете работать СЃ телом таблицы как СЃ самостоятельной таблицей. Рто же справедливо для THEAD Рё TFOOT. Обратите также внимание РЅР° получение значений, введенных РІ текстовые поля: РІ большинстве случаев можно пользоваться РЅРµ методами getAttribute() Рё setAttribute(), Р° свойствами, которые имеют такие же названия, как Рё соответствующие атрибуты.
Теперь очередь файла с кодом сценария. В примере он имеет имя script_13_4.js (JS – стандартное расширение для файлов со сценариями на JavaScript) (пример 13.5).
Пример 13.5. Файл script_13_4.js
//Функция принимает код, название, путь изображения и добавляет
//запись в таблицу function add_image(code, imagename, path){
if (valid_data(code, imagename, path)){
//Формирование строки таблицы (в части TBODY)
var row = mytable.insertRow();
//Ячейка с кодом рисунка row.insertCell().innerHTML = "<B>" + code + "</B>";
//Ячейка с названием row.insertCell().innerHTML = imagename;
//Ячейка с изображением row.insertCell().innerHTML = '<IMG width = "130" src = "'+ path +'">';
}
}
//Функция проверяет правильность введеных данных function valid_data(code, imagename, path){
//Проверка, введены ли все значения if (code == "" || imagename == "" || path == ""){
alert("Введите значения во все поля");
return false;
}
else{
//Проверим, чтобы код изображения не дублировался var i;
for (i=0; i<mytable.rows.length; i++){
if (mytable.rows(i).cells(0).innerText == code){
alert("Рзображение СЃ РєРѕРґРѕРј "+ code +" уже присутствует РІ таблице");
return false;
}
}
}
return true;
}
//Функция удаления записи из таблицы (код изображения
//вводит пользователь)
function delete_image(){
var code = prompt("Введите код удаляемого изображения", "");
if (code != null){
//Находим и удаляем запись var i;
for (i=0; i<mytable.rows.length; i++){
if (mytable.rows(i).cells(0).innerText == code){
mytable.deleteRow(i);
return true;
}
}
alert("Рзображение СЃ РєРѕРґРѕРј " + code + " РЅРµ найдено.");
}
}
Как видно, в файле script_13_4.js реализованы три функции. Первая функция add_image() используется для добавления записей в таблицу. Перед добавлением каждой новой записи она проверяет (с помощью функции valid_data()), чтобы были введены все данные (код, описание и путь изображения), а также, чтобы код нового изображения не дублировался кодом одного из изображений, ранее добавленных в таблицу. Третья функция delete_image() используется для удаления записи из таблицы.
РР· примера 13.5 можно увидеть применение коллекций rows Рё cells таблицы РЅР° практике.
Помещаем свое меню на страницу
Рассмотрим еще РѕРґРёРЅ довольно любопытный пример, позволяющий разнообразить оформление страницы. Рспользуя таблицы, CSS Рё простые сценарии, создадим СЃРІРѕРµ красочное меню. Р’ пункты этого меню можно вставлять маленькие изображения. Пункты Р±СѓРґСѓС‚ подсвечиваться РїСЂРё наведении РЅР° РЅРёС… указателя мыши. Внешний РІРёРґ меню представлен РЅР° СЂРёСЃ. 13.2.
Рис. 13.2. Внешний вид меню
Ниже приводится текст HTML‑документа с созданным меню (пример 13.6).
Пример 13.6. Документ с меню
<!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}
</STYLE>
<SCRIPT src = "menu.js" type = "text/javascript"></SCRIPT>
</HEAD>
<BODY>
<TABLE id = "menu1" class = "menu">
<!–Первый пункт меню–>
<TR id = "item1" class = "item" onClick = "item1_click()"
onMouseOver = "item1.className = 'selected'"
onMouseOut = "item1.className = 'item'">
<TD><IMG src = "icons/2.jpg"><TD>Первый пункт меню
<!–Второй пункт меню–>
<TR id = "item2" class = "item" onClick = "item2_click()"
onMouseOver = "item2.className = 'selected'"
onMouseOut = "item2.className = 'item'">
<TD><IMG src = "icons/2.jpg"><TD>Второй пункт меню
<!–Третий пункт меню–>
<TR id = "item3" class = "item" onClick = "item3_click()"
onMouseOver = "item3.className = 'selected'"
onMouseOut = "item3.className = 'item'">
<TD><IMG src = "icons/3.jpg"><TD>Третий пункт меню
<!–Четвертый пункт меню–>
<TR id = "item4" class = "item" onClick = "item4_click()"
onMouseOver = "item4.className = 'selected'"
onMouseOut = "item4.className = 'item'">
<TD><IMG src = "icons/4.jpg"><TD>Четвертый пункт меню
<!–Пятый пункт меню–>
<TR id = "item5" class = "item" onClick = "item5_click()"
onMouseOver = "item5.className = 'selected'"
onMouseOut = "item5.className = 'item'">
<TD><IMG src = "icons/5.jpg"><TD>Пятый пункт меню
</TABLE>
</BODY>
</HTML>
РР· приведенного текста можно увидеть, каким образом используется таблица: пунктами меню являются строки таблицы. Чтобы строки таблицы подсвечивались РїСЂРё наведении указателя мыши, РёС… стилевой класс динамически изменяется РїСЂРё обработке событий onMouseOver, onMouseOut. Рзменив определения стилевых классов item, selected, menu, можно легко добиться нужного РІРёРґР° меню.
При выборе каждого из пунктов меню вызывается соответствующая функция‑обработчик (см. значения атрибутов onClick для элементов TR). Все функции‑обработчики собраны в файле menu.js, текст которого приводится ниже (пример 13.7).
Пример 13.7. Содержимое файла menu.js
/*
В этом файле содержатся функции-обработчики для каждого пункта меню
*/
function item1_click(){
alert("Вы выбрали первый пункт меню");
//Другие действия...
}
function item2_click(){
alert("Вы выбрали второй пункт меню");
//Другие действия...
}
function item3_click(){
alert("Вы выбрали третий пункт меню");
//Другие действия...
}
function item4_click(){
alert("Вы выбрали четвертый пункт меню");
//Другие действия...
}
function item5_click(){
alert("Вы выбрали пятый пункт меню");
//Другие действия...
}
В каждую их приведенных выше функций помещен только код, сообщающий о работоспособности отдельного пункта меню.
Объект navigator
Глобальный объект navigator позволяет получить некоторую информацию о браузере, в котором происходит просмотр страницы со сценарием. Свойства объекта navigator, поддерживаемые большинством браузеров (по крайней мере, не только браузером Internet Explorer), приведены в табл. 13.5.
Таблица 13.5. Свойства объекта navigator
Часто использовать объект navigator нет необходимости, однако он может очень пригодиться при создании достаточно продвинутых и «живучих» веб‑страниц, способных выбирать сценарии для выполнения в зависимости от браузера, в котором они открываются. Простейший код, позволяющий отличить браузер Internet Explorer, приведен ниже (пример 13.8).
Пример 13.8. Определение браузера
function do_script(){
if (navigator.appName == "Microsoft Internet Explorer"){
//Код для Internet Explorer...
}
else{
//Код для другого браузера...
}
}
Объект window
Глобальный объект window предоставляет возможности по манипулированию окном браузера или окном фрейма, в котором открыт документ со сценарием. Кроме того, при помощи объекта window можно открывать новые окна, манипулировать фреймами, создавать таймеры (что очень нужно для анимации) и делать еще много полезного.
Свойства и методы объекта window
Основные свойства объекта window приводятся в табл. 13.6.
Таблица 13.6. Свойства объекта window
В табл. 13.7 приведены основные методы объекта window.
Таблица 13.7. Методы объекта window
Как было сказано при описании метода open() в табл. 13.7, для этого метода предусмотрено несколько дополнительных параметров. Основные параметры перечислены в табл. 13.8.
Таблица 13.8. Параметры метода open()
Каждый из приведенных в таблице параметров может добавляться в строку параметры в виде: имя_параметра = значение. Так, для открытия документа в новом окне размером 300 × 400 можно использовать следующий вызов метода open():
window.open(В«13.6.htmlВ», "", В«width = 300, height = 400В»);
Вообще, РїРѕ крайней мере РІ браузере Internet Explorer, разделителем параметров РІ строке необязательно может быть запятая. Ртот браузер нормально воспринимает РІ качестве разделителя Рё пробел, Рё точку СЃ запятой. Еще РїСЂРё испытаниях метода open() РІ Internet Explorer замечена следующая особенность: если РІ строке задан хотя Р±С‹ РѕРґРёРЅ параметр, то значения всех остальных параметров, принимающих значения 0 или 1, сбрасываются РІ 0. Так, созданное приведенным выше вызовом метода open() РѕРєРЅРѕ будет отображаться без строки состояния, панели инструментов, строки меню, полос прокрутки, строки адреса Рё будет неизменяемого размера.
Как можно было заметить, РІ табл. 13.8 приведены параметры, позволяющие задать ширину РЅРѕРІРѕРіРѕ РѕРєРЅР°, РЅРѕ РЅРµ приведены параметры, задающие положение РѕРєРЅР°. Рти параметры РІ действительности есть, РЅРѕ РѕРЅРё отличаются для различных браузеров. Для Internet Explorer это left Рё top, Р° для Navigator – screenX Рё screenY.
Примеры использования объекта window
Теперь рассмотрим, как можно использовать объект window для воспроизведения анимации в окне браузера.
Методы, позволяющие создавать таймеры, просто незаменимы РїСЂРё работе СЃ анимацией средствами браузера. Суть данного примера состоит РІ последовательной загрузке изображений РІ элемент IMG. Рнтервал между сменами кадров выдерживается СЃ помощью таймера. Всего кадров шесть (СЂРёСЃ. 13.3).
Р РёСЃ. 13.3. Рзображения-кадры
Кадры меняются от первого до шестого, а затем от шестого до первого. Текст HTML‑документа со сценарием, реализующим смену кадров, приведен ниже (пример 13.9).
Пример 13.9. Анимация на странице
<!DOCTYPE HTML PUBLIC В«-//W3C//DTD HTML 4.01 Frameset//ENВ»
"http://www.w3.org/TR/html4/frameset.dtd">
<HTML>
<HEAD>
<TITLE>Страница с анимацией</TITLE>
</HEAD>
<BODY>
<SCRIPT type = "text/javascript">
//Назначаем функцию, вызываемую по таймеру и меняющую
//изображения window.setInterval(new_frame, 300);
var inc = 1;
var curFrame = 1;
var maxFrame = 6;
//Функия смены кадров function new_frame(){
//Покажем текущий кадр animate.src = "frames/" + curFrame + ".gif";
//Переход на следующий кадр curFrame += inc;
if (curFrame > maxFrame){
//Начинаем воспроизведение в обратном порядке curFrame = maxFrame;
inc = –1;
}
else if (curFrame == 0){
//Начинаем воспроизведение в прямом порядке curFrame = 1;
inc = 1;
}
}
</SCRIPT>
<IMG id = "animate" src = "frames/1.gif">
</BODY>
</HTML>
В коде сценария количество кадров задается в переменной maxFrames. Предполагается, что кадры помещаются в папке frames и имеют имена вида номер.gif.
Создание всплывающих окон
РРЅРѕРіРґР° бывает СѓРґРѕР±РЅРѕ использовать дополнительные так называемые всплывающие РѕРєРЅР°, например, чтобы открывать РІ РЅРёС… СЃРїРёСЃРѕРє файлов для закачки, если речь идет Рѕ каком‑то веб‑архиве. Как РІС‹ уже догадались, РІ этом примере для открытия новых РѕРєРѕРЅ используется метод open() объекта window. РљСЂРѕРјРµ открытия РЅРѕРІРѕРіРѕ РѕРєРЅР°, РІ приведенном ниже примере 13.10 реализовано также его закрытие через 5 секунд.
Пример 13.10. Создание и закрытие всплывающего окна
<!DOCTYPE HTML PUBLIC В«-//W3C//DTD HTML 4.01 Frameset//ENВ»
"http://www.w3.org/TR/html4/frameset.dtd">
<HTML>
<HEAD>
<TITLE>Всплывающие окна</TITLE>
</HEAD>
<BODY>
<SCRIPT type = "text/javascript">
//Функция открывает окно\
function open_window(){
wnd = window.open("13.9.html", "asd", "height = 200, width = 350");
//Функция закрытия окна вызывается через 5 секунд window.setTimeout(wnd.close, 5000);
}
</SCRIPT>
<P>Щелкните
<INPUT type = "button" value = "РєРЅРѕРїРєСѓ" onClick = "open_window()">
чтобы открыть новое окно на 5 секунд.
</BODY>
</HTML>
Помните, что использовать всплывающие окна следует оправданно. Чаще всего пользователя очень раздражают появляющиеся неожиданно окна, например с какой‑нибудь рекламой.
Объект style
Объект style, который для большинства элементов страницы поддерживается как свойство, предоставляет большие возможности РїРѕ манипулированию стилем элементов. Рти возможности такие же, как Рё доступные РїСЂРё использовании таблиц стилей: можно получать Рё указывать значения тех же свойств, что Рё СЃ использованием CSS. Сначала рассмотрим, как формируются имена свойств объекта style.
Свойства объекта style
Ртак, имена свойств CSS, состоящие РёР· РѕРґРЅРѕРіРѕ слова, РІ таком же РІРёРґРµ Рё используются как имена свойств объекта style, например:
el.style.width = 100;
el.style.color = "red";
Здесь el предоставляет доступ к элементу страницы со значением атрибута id, равным «el».
В приложении 2, где приведен список основных свойств CSS, можно увидеть, что названия многих свойств состоят из нескольких слов, разделенных символом –. Так вот, имена таких свойств CSS преобразуются в имена свойств объекта style следующим образом: первое слово имени записывается cо строчной буквы, остальные слова начинаются с прописной буквы, все символы – из имени свойства удаляются. Ниже приведен пример для того же элемента el:
el.style.borderStyle = «solid»; //свойство border-style
el.style.borderColor = "blue"; //свойство border-color
el.style.borderBottomWidth = "10mm"; //свойство border-bottom-width
Как видно, значения свойств могут быть в тех же единицах измерения, которые применяются для CSS. Однако это хорошо до тех пор, пока не нужно производить вычисления с использованием текущих параметров элемента. Так, в приведенном выше примере el.style.borderBottomWidth вернет строковое значение «10mm». Удобно ли производить вычисления с такими значениями? В табл. 13.9 приведен перечень дополнительных свойств, поддерживаемых только интерпретатором браузера Internet Explorer, но значительно облегчающих программирование таких вещей, как перемещение элементов страницы.
Таблица 13.9. Дополнительные свойства объекта style
Примечание
При использовании описанных в этом разделе свойств объекта style следует учитывать одну неприятную особенность: до того, как сценарий может получить значение свойства, это значение должно быть установлено также с использованием сценария.
Примеры использования объекта style
Теперь рассмотрим три примера, иллюстрирующих возможности элемента style. Первые два из них связаны с анимацией, а в последнем примере приводится реализация усовершенствованного меню на основе таблицы.
В первом примере реализуется перемещение изображений«шариков» внутри рамки (элемент DIV). Шарики имеют случайные первоначальные скорости и направления движения. Кроме того, при достижении стенок (рамки элемента DIV) они упруго он них отталкиваются. Страница примера выглядит так, как показано на рис. 13.4.
Рис. 13.4. Перемещение «шариков» внутри элемента DIV
Ниже приведен текст HTML‑документа, который показан на рис. 13.4 (пример 13.11).
Пример 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">
//Позиционируем элемент DIV
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).
Пример 13.12. Содержимое файла balls.js
//Массив со ссылками на объекты-изображения шариков 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).
Пример 13.13. Содержимое файла coloredtext.js
//Поиск всех элементов, имеющих класс «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 + ")";
}
}
Ртот сценарий работает следующим образом. После загрузки содержимого документа (для этого файл должен подключаться Рє документу перед закрывающим тегом