Наиболее зрелищные эффекты при программировании на JavaScript достигаются при работе с Image, комбинирование картинок с гипертекстовыми ссылками и таблицами. Тем не менее обилие различных эффектов, которые достигаются этими нехитрыми средствами, впечатляет.
Программирование графики в JavaScript опирается на объект Image, который характеризуется следующими свойствами, методами и событиями:
| Свойства | Методы | События |
|---|---|---|
name src lowSrc border height width hspace vspace complete |
нет | Abort Error Load |
Несмотря на такое обилие свойств, их абсолютное большинство можно только читать, но не изменять. Об этом свидетельствует, прежде всего, отсутствие методов. Но два свойства все же можно изменять: src и lowSrc. Этого оказывается достаточно для множества эффектов с картинками.
Все объекты класса Image можно разделить на встроенные и порожденные программистом. IMG. Если эти картинки поименовать, к ним можно обращаться по имени. Например, если у нас имеется картинка (будем считать, что она первая в документе):
<IMG NAME=picname SRC=forest.gif>
то значение свойства document.images[0].name будет равно " picname ", а к самой картинке можно будет обращаться тремя способами:
document.images[0] document.picname document.images['picname']
Свойства src и lowSrc определяют URL изображения, которое монтируется внутрь документа. При этом lowSrc определяет временное изображение, обычно маленькое, которое отображается, пока загружается основное изображение, чей URL указывается в атрибуте SRC контейнера IMG. Свойство src принимает значение атрибута SRC контейнера IMG. Программист может изменять значения и src, и lowSrc. В предыдущем примере мы можем изменить значение src следующим образом:
document.picname.src='river.gif';
Как видно из этого примера, существует возможность модифицировать картинку за счет изменения значения свойства src встроенного объекта Image. Если вы в первый раз просматриваете данную страницу (т.е. картинки не закешированы браузером), то постепенное изменение картинки будет заметно (конечно, при низкой скорости подключения к Internet; а также это зависит от браузера, который может загрузить картинку, а только потом вывести ее целиком на страницу). Как ускорить это изменение, мы рассмотрим в следующем разделе.
Изменить картинку можно, только присвоив свойству src встроенного объекта Image новое значение. Выше было показано, как это делается в простейшем случае. Очевидно, что медленная перезагрузка картинки с сервера не позволяет реализовать быстрое листание. Попробуем решить эту проблему. (Последующее в этом
Пример 7.1 (кликните, чтобы открыть в новом окне; для просмотра HTML-кода кликните правой кнопкой мыши и выберите соответствующий пункт)
Решение заключается в разведении по времени подкачки картинки и ее отображения. Для начала мы создаем изображения, к которым привязываем обработчики событий onMouseOver и onMouseOut. При наведении указателя мыши на каждую из картинок она заменяется другой (цветной), а при уводе мышки картинка заменяется обратно на черно-белую:
<IMG NAME=m0 src="images/mapb000.gif" border=0
onMouseOver="document.m0.src=color[0].src;"
onMouseOut="document.m0.src= mono[0].src;">
Более того, если навести мышку на пункт меню справа от карты, то вызовется функция, которая заменяет адреса сразу у нескольких картинок.
Однако, главное не в том, что картинки замещаются, а в том, с какой скоростью они это делают. Для достижения нужного результата в начале страницы создаются массивы картинок, в которые перед отображением перекачивается вся графика. Для этой цели используют конструктор объекта Image:
mono = new Array(32);
for(i=0;i<32;i++)
{
mono[i] = new Image();
s = (i<10)? "0" : "";
mono[i].src = "images/mapb0" +s+i+ ".gif";
}
Именно в тот момент, когда свойству, например, mono[25].src присвавается значение " images/mapb025.gif ", и происходит скачивание этой картинки с сайта на компьютер пользователя. Если бы вместо объектов класса Image мы составили массив из строк вида " images/mapb000.gif " и т.д., то никакой подгрузки графики не произошло бы, и каждый раз, когда пользователь наводил бы на очередное изображение, браузеру приходилось бы скачивать новую картинку. Мы поместили этот скрипт в контейнер <HEAD>, тем самым гарантировав, что к моменту, когда пользователь начнет работать со страницей, все требуемые для работы картинки уже будут скачаны, и в процессе вождения мышки по картинкам никакой задержки показа очередного изображения наблюдаться не будет.
Попутно обратим внимание на следующий трюк, использованный в скрипте. Предположим, нам необходимо написать 32 строчки:
document.m0.src = mono[0].src; document.m1.src = mono[1].src; ... document.m31.src = mono[31].src;
Мы хотим избежать написания такого громоздкого кода. С правой частью i от 0 до 31 и писать mono[i].src. А вот с левой частью не все так просто. На помощь приходит функция , которая воспринимает переданное ей выражение как программу JavaScript и выполняет все содержащиеся в ней операторы. С ее помощью решить нашу проблему легко - мы составляем нужную строчку, а затем отдаем ее на выполнение:
for(i=0;i<32;i++)
eval("document.m" +i+ ".src = mono[" +i+ "].src;");
Естественным продолжением идеи замещения значения атрибута ).
Существует два способа запуска onLoad ) и при действиях пользователя ( , и т.д.). Наиболее популярный - первый, а именно использование onLoad() и .
Событие наступает в момент окончания загрузки документа браузером. Обработчик данного события ( onLoad ) указывается в контейнере BODY:
<BODY onLoad="программа JavaScript">
Рассмотрим сначала пример, в котором при загрузке документа начинает выполняться бесконечный цикл изменения картинки:
<SCRIPT>
var i=0;
function movie()
{
document.i.src='images/crou00'+i+'.gif';
i++; if(i>4) i=0;
setTimeout('movie();',500);
}
</SCRIPT>
<BODY onLoad="movie();">
<IMG NAME=i>
</BODY>
Можно реализовать и конечное число циклов 5:
<SCRIPT>
var i=0,
n=5; // число циклов
function movie()
{
document.i.src='images/crou00'+i+'.gif';
i++; if(i>4) { i=0; n--; }
if(n>0) setTimeout('movie();',500);
}
</SCRIPT>
<BODY onLoad="movie();">
<IMG NAME=i>
</BODY>
В обоих примерах следует обратить внимание на использование метода . На первый взгляд, это просто
movie() получает управление от обработчика события onLoad ;movie() и откладывает его исполнение на 500 миллисекунд;movie() уничтожается JavaScript-интерпретатором.После окончания срока задержки исполнения все повторяется. В первом примере (бесконечное повторение) функция порождает саму себя и, тем самым, поддерживает непрерывность своего выполнения. Во втором примере (конечное число итераций) после нескольких повторов функция не порождается. Это приводит к
Постоянная
<SCRIPT>
var i=0, flag=true;
function movie()
{
if(flag)
{
document.i.src='images/crou00'+i+'.gif';
i++; if(i>4) i=0;
}
setTimeout('movie();',500);
}
</SCRIPT>
<BODY onLoad="movie();">
<FORM>
<INPUT TYPE=button VALUE="Start/Stop"
onClick="flag = !flag;">
</FORM>
<IMG NAME=i>
</BODY>
Мы ввели булевский и меняем изображение на странице, только если он принимает значение true. Нажатие на кнопку меняет значение флага на его
Обратите внимание: когда имеет значение false, мы просто обходим изменение картинки, но не прекращаем порождение потока. Если бы мы поместили внутрь конструкции if(), то после нажатия на кнопку поток перестал бы порождаться, и запустить мультипликацию заново стало бы нельзя. Однако постоянное генерирование потока - это некоторая растрата ресурсов (памяти, процессора). Нельзя ли сделать оптимальнее? Можно. Этот способ основан на применении метода clearTimeout():
<SCRIPT>
var i=0, flag=true, m=null;
function movie()
{
if(flag)
{
document.i.src='images/crou00'+i+'.gif';
i++; if(i>4) i=0;
}
m = setTimeout('movie();',500);
}
</SCRIPT>
<BODY onLoad="movie();">
<IMG NAME=i>
<FORM>
<INPUT TYPE=button VALUE="Start/Stop"
onClick="flag = !flag;
if(flag) movie();
else clearTimeout(m);">
</FORM>
</BODY>
Как видите, достаточно ввести идентификатор потока m и сохранять в нем ссылку на поток при вызове . Тогда в случае необходимости (при нажатии пользователем кнопки) мы можем отменить запланированное выполнение movie() (которое произошло бы через 500 миллисекунд), вызвав метод clearTimeout(m).
При программировании графики следует учитывать множество факторов, которые влияют на скорость отображения страницы и скорость изменения графических образов. При этом обычная дилемма
Из всех способов оптимизации отображения картинок мы остановимся только на нескольких:
Если первые две позиции относятся в равной степени как к отображению статических картинок, так и к
Практически в любом руководстве по разработке HTML-страниц отмечается, что при использовании контейнера IMG в теле HTML-страницы следует указывать атрибуты WIDTH и HEIGHT. Это продиктовано порядком загрузки компонентов страницы с сервера и алгоритмом работы HTML-
Также параллельно с загрузкой
Таким образом указание высоты и ширины картинки позволит отобразить документ раньше, чем картинки будут получены с сервера. Это дает пользователю возможность читать документ или задействовать его гипертекстовые ссылки до момента полной загрузки документа.
С точки зрения JavaScript, указание размеров картинки задает начальные параметры окна отображения графики внутри документа. Это позволяет воспользоваться маленьким прозрачным образом, для того, чтобы заменить его полноценной картинкой. Идея состоит в передаче маленького объекта для замещения его по требованию большим объектом.
Замена одного образа другим часто бывает оправдана только в том случае, когда это происходит достаточно быстро. Если перезагрузка длится долго, то эффект теряется. Для быстрой подмены используют возможность предварительной загрузки документа в специально созданный объект класса Image.
Реальный эффект можно почувствовать только при отключении
Описанный выше прием неоднозначен. Его оправдывает только то, что если пользователь нетерпелив, то он вообще отключит передачу графики.
Нарезка картинок применяется довольно часто. Она позволяет достигать эффекта частичного изменения отображаемой картинки. Чаще всего он применяется при создании меню.
Кроме подобного эффекта нарезка позволяет реализовать мультипликацию на больших картинках. При этом изменяется не весь образ, а только отдельные его части.
Одним из наиболее популярных приемов дизайна страниц Web-узла является техника нарезки картинок на составные части. Можно выделить следующие способы применения этой техники для организации навигационных компонентов страницы:
Главной проблемой при использовании нарезанной графики является защита ее от контекстного форматирования страницы HTML-
Пример 7.2. Откройте данный пример в новом окне и попробуйте уменьшить ширину окна, так чтобы она стала меньше общей ширины всех картинок. Вы увидите, что картинки начинают переноситься на новую строку, когда ширина раздела становится меньше общей ширины всех картинок:
<IMG SRC="horis1.gif"><IMG
SRC="horis2.gif"><IMG
SRC="horis3.gif"><IMG
SRC="horis4.gif">
(рис 7.1) Горизонтальное меню (картинки съезжают в узком окне)Пример 7.3. Проблема решается применением "защиты" от переноса на следующую строчку - контейнера <:
<PRE>
<IMG SRC="horis1.gif"><IMG
SRC="horis2.gif"><IMG
SRC="horis3.gif"><IMG
SRC="horis4.gif">
</PRE>
(рис 7.2) Горизонтальное меню (картинки защищены от переноса)Пример 7.4. Если мы хотим использовать эту последовательность картинок как меню, то нужно задать гипертекстовые ссылки, что приводит к появлению рамок вокруг изображений. Это происходит потому, что по умолчанию толщина границ у изображений, являющихся ссылками - ненулевая.
<PRE> <A HREF="courses.htm"><IMG SRC="horis1.gif"></A><A HREF="setting.htm"><IMG SRC="horis2.gif"></A><A HREF="baskets.htm"><IMG SRC="horis3.gif"></A><A HREF="thehelp.htm"><IMG SRC="horis4.gif"></A> </PRE>
(рис 7.3) Горизонтальное меню (рамки вокруг картинок)Пример 7.5. Устранить этот недостаток можно путем задания значения атрибута BORDER=0 у изображений:
<PRE> <A HREF="courses.htm"><IMG SRC="horis1.gif" BORDER=0></A><A HREF="setting.htm"><IMG SRC="horis2.gif" BORDER=0></A><A HREF="baskets.htm"><IMG SRC="horis3.gif" BORDER=0></A><A HREF="thehelp.htm"><IMG SRC="horis4.gif" BORDER=0></A> </PRE>
(рис 7.4) Горизонтальное меню (рамки более не видны)
Пример 7.6. Теперь попробуем тем же способом реализовать вертикальное меню. При просмотре в некоторых браузерах сплошной вертикальной линии не получается, т.к. высота строки не равна высоте картинки. Подогнать эти параметры практически невозможно. Каждый пользователь настраивает браузер по своему вкусу.
<PRE> <IMG SRC=vert.gif WIDTH=27 HEIGHT=21 BORDER=0><A HREF="courses.htm"><IMG SRC="vert1.gif" WIDTH=103 HEIGHT=21 BORDER=0></A> <IMG SRC=vert.gif WIDTH=27 HEIGHT=21 BORDER=0><A HREF="setting.htm"><IMG SRC="vert2.gif" WIDTH=103 HEIGHT=21 BORDER=0></A> <!-- далее аналогично для vert3.gif и vert4.gif --> </PRE>
(рис 7.5) Вертикальное меню (линия не сплошная)Пример 7.7. Решение заключается в использовании (вместо контейнера < ) таблицы <TABLE> с нулевыми границами между ячейками:
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR>
<TD><IMG SRC=vert.gif WIDTH=27 HEIGHT=21 BORDER=0></TD>
<TD><A HREF="courses.htm"><IMG SRC="vert1.gif"
WIDTH=103 HEIGHT=21 BORDER=0></A></TD>
</TR>
<!-- далее аналогично для vert2, vert3, vert4.gif -->
</TABLE>
(рис 7.6) Вертикальное меню (линия сплошная)В данном случае все картинки удается сшить без пропусков и тем самым достичь непрерывности навигационного дерева. Пропуски устраняются путем применения атрибутов BORDER, CELLPADDING и CELLSPACING. Первый устраняет границы между ячейками и вокруг всей таблицы, второй устанавливает расстояние между ячейками равным 0 пикселов, третий устанавливает отступ между границей ячейки и элементом, помещенным в нее, в 0 пикселов.
Практически все, что было изложено до сих пор, касается вопросов построения одноуровневых меню. Поэтому в данном разделе мы постараемся привести более или менее реальные примеры таких меню. Графическое меню удобно тем, что автор может всегда достаточно точно расположить его компоненты на экране. Это, в свою очередь, позволяет и другие элементы страницы точнее располагать относительно элементов меню.
Пример 7.8. В данном примере мы воспользуемся этим для того, чтобы выделить тот пункт меню, над которым находится указатель мыши. Поскольку пункты меню прилегают друг к другу без просветов, то мы будем указывать стрелочкой тот пункт меню, который активен в данный момент.
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0> <TR ALIGN="center"> <TD> <IMG NAME=e1 SRC=empty.gif WIDTH=15 HEIGHT=8 BORDER=0> </TD> <!-- аналогично для e2, e3, e4 --> </TR> <TR> <TD><A HREF="javascript:void(0);" onMouseOver="document.e1.src='arrowdw.gif';" onMouseOut="document.e1.src='empty.gif';"> <IMG SRC="horis1.gif" BORDER="0"></A> </TD> <!-- аналогично для e2, e3, e4 --> </TR> </TABLE>
(рис 7.7) Горизонтальное меню (пункт указан стрелкой)Стрелочка бежит точно над тем элементом, на который указывает мышь.
Пример 7.9. Однако стоит заметить, что применение атрибута ALT у контейнера IMG и его дублирование в строке статуса является гораздо более информативным, чем добавление нового графического элемента. Правда, отображается содержание ALT с некоторой задержкой:
<PRE> <A HREF="courses.htm" onMouseOut="window.status='';" onMouseOver="window.status='Мои курсы';return true;"><IMG SRC="horis1.gif" BORDER=0 ALT="Мои курсы"></A><A HREF="setting.htm" onMouseOut="window.status='';" onMouseOver="window.status='Настройки';return true;"><IMG SRC="horis2.gif" BORDER=0 ALT="Настройки"></A><A HREF="baskets.htm" onMouseOut="window.status='';" onMouseOver="window.status='Корзина';return true;"><IMG SRC="horis3.gif" BORDER=0 ALT="Корзина"></A><A HREF="thehelp.htm" onMouseOut="window.status='';" onMouseOver="window.status='Помощь';return true;"><IMG SRC="horis4.gif" BORDER=0 ALT="Помощь"></A> </PRE>
(рис 7.8) Горизонтальное меню (атрибут ALT и поле статуса)Пример 7.10. Посмотрим теперь на реализацию вертикального меню, построенного на основе графических блоков текста:
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
<SCRIPT>
for(i=1; i<5; i++)
{ var
ileft = '<IMG SRC=block'+i+'.gif border=0>',
iright = '<IMG NAME=e'+i+' SRC=clear.gif border=0>',
isrc = 'document.e'+i+'.src',
alink = '<A HREF="javascript:void(0);" '+
'onMouseover="'+isrc+'=\'corner.gif\';" '+
'onMouseout="'+ isrc+'=\'clear.gif\';">';
document.write('<TR>'+
'<TD>'+ alink + ileft + '</A></TD>'+
'<TD>'+ alink + iright + '</A></TD>'+
'</TR>');
}
</SCRIPT>
</TABLE>
Здесь продемонстрировано типичное применение JavaScript - многократное генерирование похожих фрагментов HTML-кода с помощью цикла и метода document.write(). В данном примере с помощью цикла мы генерируем HTML-фрагмент следующего вида (каждый раз с разным номером вместо "1"):
<TR>
<TD><A onMouseover="document.e1.src='corner.gif';"
onMouseout="document.e1.src='clear.gif';"
HREF="javascript:void(0);"><IMG SRC=block1.gif border=0></A></TD>
<TD><A onMouseover="document.e1.src='corner.gif';"
onMouseout="document.e1.src='clear.gif';"
HREF="javascript:void(0);"><IMG NAME=e1 SRC=clear.gif border=0></A></TD>
</TR>
При движении мыши у соответствующего пункта меню, попавшего в фокус мыши, "отгибается уголок". В данном случае "уголок" - это самостоятельная картинка. Все уголки реализованы в правой колонке таблицы. Для того чтобы гипертекстовая ссылка срабатывала по обеим картинкам (тексту и "уголку"), применяются одинаковые контейнеры <A>, охватывающие каждую картинку.
(рис 7.9) Вертикальное меню (графические блоки текста)
В HTML нет стандартного способа реализации вложенных меню. Тем не менее за счет графики можно создать их подобие. При этом следует понимать, что место, на которое ложится графика, нельзя заполнить текстом.
Пример 7.11. В этом примере вложенное меню расположено справа от основного. Эффект вложенности достигается за счет изменения цвета (подпункты имеют цвет, отличный от цвета пунктов).
<SCRIPT>
function submenu(a)
{
with(document)
{
if(a==1)
{
item1.src="item_1_yes.gif"; // 1-й пункт активен
item2.src="item_2_no.gif"; // 2-й пункт неактивен
subi1.src="item_1_1.gif"; // 1-й пункт вложенного меню 1
subi2.src="item_1_2.gif"; // 2-й пункт вложенного меню 1
}
if(a==2)
{
item1.src="item_1_no.gif"; // 2-й пункт активен
item2.src="item_2_yes.gif"; // 1-й пункт неактивен
subi1.src="item_2_1.gif"; // 1-й пункт вложенного меню 2
subi2.src="item_2_2.gif"; // 2-й пункт вложенного меню 2
}
}
}
</SCRIPT>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=1>
<TR>
<TD><A HREF="javascript:void(0);" onMouseOver="submenu(1);">
<IMG BORDER=0 NAME=item1 SRC=item_1_yes.gif></A></TD>
<TD><IMG BORDER=0 NAME=subi1 SRC=item_1_1.gif></TD></TR>
<TR>
<TD><A HREF="javascript:void(0);" onMouseOver="submenu(2);">
<IMG BORDER=0 NAME=item2 SRC=item_2_no.gif></A></TD>
<TD><IMG BORDER=0 NAME=subi2 SRC=item_1_2.gif></TD></TR>
</TABLE>
(рис 7.10) Вложенное меню (пункт выделен цветом)Подчиненность меню можно подчеркнуть изменением его положения относительно основного меню (составьте соответствующий код самостоятельно):
(рис 7.11) Вложенное меню (пункт выделен сдвигом)В этом случае для продвижения меню вниз необходимо зарезервировать место при помощи невидимых или видимых картинок.
При использовании слоев можно создать настоящее выпадающее меню.
Наиболее зрелищные эффекты при программировании на JavaScript достигаются при работе с Image, комбинирование картинок с гипертекстовыми ссылками и таблицами. Тем не менее обилие различных эффектов, которые достигаются этими нехитрыми средствами, впечатляет.
Программирование графики в JavaScript опирается на объект Image, который характеризуется следующими свойствами, методами и событиями:
| Свойства | Методы | События |
|---|---|---|
name src lowSrc border height width hspace vspace complete |
нет | Abort Error Load |
Несмотря на такое обилие свойств, их абсолютное большинство можно только читать, но не изменять. Об этом свидетельствует, прежде всего, отсутствие методов. Но два свойства все же можно изменять: src и lowSrc. Этого оказывается достаточно для множества эффектов с картинками.
Все объекты класса Image можно разделить на встроенные и порожденные программистом. IMG. Если эти картинки поименовать, к ним можно обращаться по имени. Например, если у нас имеется картинка (будем считать, что она первая в документе):
<IMG NAME=picname SRC=forest.gif>
то значение свойства document.images[0].name будет равно " picname ", а к самой картинке можно будет обращаться тремя способами:
document.images[0] document.picname document.images['picname']
Свойства src и lowSrc определяют URL изображения, которое монтируется внутрь документа. При этом lowSrc определяет временное изображение, обычно маленькое, которое отображается, пока загружается основное изображение, чей URL указывается в атрибуте SRC контейнера IMG. Свойство src принимает значение атрибута SRC контейнера IMG. Программист может изменять значения и src, и lowSrc. В предыдущем примере мы можем изменить значение src следующим образом:
document.picname.src='river.gif';
Как видно из этого примера, существует возможность модифицировать картинку за счет изменения значения свойства src встроенного объекта Image. Если вы в первый раз просматриваете данную страницу (т.е. картинки не закешированы браузером), то постепенное изменение картинки будет заметно (конечно, при низкой скорости подключения к Internet; а также это зависит от браузера, который может загрузить картинку, а только потом вывести ее целиком на страницу). Как ускорить это изменение, мы рассмотрим в следующем разделе.
Изменить картинку можно, только присвоив свойству src встроенного объекта Image новое значение. Выше было показано, как это делается в простейшем случае. Очевидно, что медленная перезагрузка картинки с сервера не позволяет реализовать быстрое листание. Попробуем решить эту проблему. (Последующее в этом
Пример 7.1 (кликните, чтобы открыть в новом окне; для просмотра HTML-кода кликните правой кнопкой мыши и выберите соответствующий пункт)
Решение заключается в разведении по времени подкачки картинки и ее отображения. Для начала мы создаем изображения, к которым привязываем обработчики событий onMouseOver и onMouseOut. При наведении указателя мыши на каждую из картинок она заменяется другой (цветной), а при уводе мышки картинка заменяется обратно на черно-белую:
<IMG NAME=m0 src="images/mapb000.gif" border=0
onMouseOver="document.m0.src=color[0].src;"
onMouseOut="document.m0.src= mono[0].src;">
Более того, если навести мышку на пункт меню справа от карты, то вызовется функция, которая заменяет адреса сразу у нескольких картинок.
Однако, главное не в том, что картинки замещаются, а в том, с какой скоростью они это делают. Для достижения нужного результата в начале страницы создаются массивы картинок, в которые перед отображением перекачивается вся графика. Для этой цели используют конструктор объекта Image:
mono = new Array(32);
for(i=0;i<32;i++)
{
mono[i] = new Image();
s = (i<10)? "0" : "";
mono[i].src = "images/mapb0" +s+i+ ".gif";
}
Именно в тот момент, когда свойству, например, mono[25].src присвавается значение " images/mapb025.gif ", и происходит скачивание этой картинки с сайта на компьютер пользователя. Если бы вместо объектов класса Image мы составили массив из строк вида " images/mapb000.gif " и т.д., то никакой подгрузки графики не произошло бы, и каждый раз, когда пользователь наводил бы на очередное изображение, браузеру приходилось бы скачивать новую картинку. Мы поместили этот скрипт в контейнер <HEAD>, тем самым гарантировав, что к моменту, когда пользователь начнет работать со страницей, все требуемые для работы картинки уже будут скачаны, и в процессе вождения мышки по картинкам никакой задержки показа очередного изображения наблюдаться не будет.
Попутно обратим внимание на следующий трюк, использованный в скрипте. Предположим, нам необходимо написать 32 строчки:
document.m0.src = mono[0].src; document.m1.src = mono[1].src; ... document.m31.src = mono[31].src;
Мы хотим избежать написания такого громоздкого кода. С правой частью i от 0 до 31 и писать mono[i].src. А вот с левой частью не все так просто. На помощь приходит функция , которая воспринимает переданное ей выражение как программу JavaScript и выполняет все содержащиеся в ней операторы. С ее помощью решить нашу проблему легко - мы составляем нужную строчку, а затем отдаем ее на выполнение:
for(i=0;i<32;i++)
eval("document.m" +i+ ".src = mono[" +i+ "].src;");
Естественным продолжением идеи замещения значения атрибута ).
Существует два способа запуска onLoad ) и при действиях пользователя ( , и т.д.). Наиболее популярный - первый, а именно использование onLoad() и .
Событие наступает в момент окончания загрузки документа браузером. Обработчик данного события ( onLoad ) указывается в контейнере BODY:
<BODY onLoad="программа JavaScript">
Рассмотрим сначала пример, в котором при загрузке документа начинает выполняться бесконечный цикл изменения картинки:
<SCRIPT>
var i=0;
function movie()
{
document.i.src='images/crou00'+i+'.gif';
i++; if(i>4) i=0;
setTimeout('movie();',500);
}
</SCRIPT>
<BODY onLoad="movie();">
<IMG NAME=i>
</BODY>
Можно реализовать и конечное число циклов 5:
<SCRIPT>
var i=0,
n=5; // число циклов
function movie()
{
document.i.src='images/crou00'+i+'.gif';
i++; if(i>4) { i=0; n--; }
if(n>0) setTimeout('movie();',500);
}
</SCRIPT>
<BODY onLoad="movie();">
<IMG NAME=i>
</BODY>
В обоих примерах следует обратить внимание на использование метода . На первый взгляд, это просто
movie() получает управление от обработчика события onLoad ;movie() и откладывает его исполнение на 500 миллисекунд;movie() уничтожается JavaScript-интерпретатором.После окончания срока задержки исполнения все повторяется. В первом примере (бесконечное повторение) функция порождает саму себя и, тем самым, поддерживает непрерывность своего выполнения. Во втором примере (конечное число итераций) после нескольких повторов функция не порождается. Это приводит к
Постоянная
<SCRIPT>
var i=0, flag=true;
function movie()
{
if(flag)
{
document.i.src='images/crou00'+i+'.gif';
i++; if(i>4) i=0;
}
setTimeout('movie();',500);
}
</SCRIPT>
<BODY onLoad="movie();">
<FORM>
<INPUT TYPE=button VALUE="Start/Stop"
onClick="flag = !flag;">
</FORM>
<IMG NAME=i>
</BODY>
Мы ввели булевский и меняем изображение на странице, только если он принимает значение true. Нажатие на кнопку меняет значение флага на его
Обратите внимание: когда имеет значение false, мы просто обходим изменение картинки, но не прекращаем порождение потока. Если бы мы поместили внутрь конструкции if(), то после нажатия на кнопку поток перестал бы порождаться, и запустить мультипликацию заново стало бы нельзя. Однако постоянное генерирование потока - это некоторая растрата ресурсов (памяти, процессора). Нельзя ли сделать оптимальнее? Можно. Этот способ основан на применении метода clearTimeout():
<SCRIPT>
var i=0, flag=true, m=null;
function movie()
{
if(flag)
{
document.i.src='images/crou00'+i+'.gif';
i++; if(i>4) i=0;
}
m = setTimeout('movie();',500);
}
</SCRIPT>
<BODY onLoad="movie();">
<IMG NAME=i>
<FORM>
<INPUT TYPE=button VALUE="Start/Stop"
onClick="flag = !flag;
if(flag) movie();
else clearTimeout(m);">
</FORM>
</BODY>
Как видите, достаточно ввести идентификатор потока m и сохранять в нем ссылку на поток при вызове . Тогда в случае необходимости (при нажатии пользователем кнопки) мы можем отменить запланированное выполнение movie() (которое произошло бы через 500 миллисекунд), вызвав метод clearTimeout(m).
При программировании графики следует учитывать множество факторов, которые влияют на скорость отображения страницы и скорость изменения графических образов. При этом обычная дилемма
Из всех способов оптимизации отображения картинок мы остановимся только на нескольких:
Если первые две позиции относятся в равной степени как к отображению статических картинок, так и к
Практически в любом руководстве по разработке HTML-страниц отмечается, что при использовании контейнера IMG в теле HTML-страницы следует указывать атрибуты WIDTH и HEIGHT. Это продиктовано порядком загрузки компонентов страницы с сервера и алгоритмом работы HTML-
Также параллельно с загрузкой
Таким образом указание высоты и ширины картинки позволит отобразить документ раньше, чем картинки будут получены с сервера. Это дает пользователю возможность читать документ или задействовать его гипертекстовые ссылки до момента полной загрузки документа.
С точки зрения JavaScript, указание размеров картинки задает начальные параметры окна отображения графики внутри документа. Это позволяет воспользоваться маленьким прозрачным образом, для того, чтобы заменить его полноценной картинкой. Идея состоит в передаче маленького объекта для замещения его по требованию большим объектом.
Замена одного образа другим часто бывает оправдана только в том случае, когда это происходит достаточно быстро. Если перезагрузка длится долго, то эффект теряется. Для быстрой подмены используют возможность предварительной загрузки документа в специально созданный объект класса Image.
Реальный эффект можно почувствовать только при отключении
Описанный выше прием неоднозначен. Его оправдывает только то, что если пользователь нетерпелив, то он вообще отключит передачу графики.
Нарезка картинок применяется довольно часто. Она позволяет достигать эффекта частичного изменения отображаемой картинки. Чаще всего он применяется при создании меню.
Кроме подобного эффекта нарезка позволяет реализовать мультипликацию на больших картинках. При этом изменяется не весь образ, а только отдельные его части.
Одним из наиболее популярных приемов дизайна страниц Web-узла является техника нарезки картинок на составные части. Можно выделить следующие способы применения этой техники для организации навигационных компонентов страницы:
Главной проблемой при использовании нарезанной графики является защита ее от контекстного форматирования страницы HTML-
Пример 7.2. Откройте данный пример в новом окне и попробуйте уменьшить ширину окна, так чтобы она стала меньше общей ширины всех картинок. Вы увидите, что картинки начинают переноситься на новую строку, когда ширина раздела становится меньше общей ширины всех картинок:
<IMG SRC="horis1.gif"><IMG
SRC="horis2.gif"><IMG
SRC="horis3.gif"><IMG
SRC="horis4.gif">
(рис 7.1) Горизонтальное меню (картинки съезжают в узком окне)Пример 7.3. Проблема решается применением "защиты" от переноса на следующую строчку - контейнера <:
<PRE>
<IMG SRC="horis1.gif"><IMG
SRC="horis2.gif"><IMG
SRC="horis3.gif"><IMG
SRC="horis4.gif">
</PRE>
(рис 7.2) Горизонтальное меню (картинки защищены от переноса)Пример 7.4. Если мы хотим использовать эту последовательность картинок как меню, то нужно задать гипертекстовые ссылки, что приводит к появлению рамок вокруг изображений. Это происходит потому, что по умолчанию толщина границ у изображений, являющихся ссылками - ненулевая.
<PRE> <A HREF="courses.htm"><IMG SRC="horis1.gif"></A><A HREF="setting.htm"><IMG SRC="horis2.gif"></A><A HREF="baskets.htm"><IMG SRC="horis3.gif"></A><A HREF="thehelp.htm"><IMG SRC="horis4.gif"></A> </PRE>
(рис 7.3) Горизонтальное меню (рамки вокруг картинок)Пример 7.5. Устранить этот недостаток можно путем задания значения атрибута BORDER=0 у изображений:
<PRE> <A HREF="courses.htm"><IMG SRC="horis1.gif" BORDER=0></A><A HREF="setting.htm"><IMG SRC="horis2.gif" BORDER=0></A><A HREF="baskets.htm"><IMG SRC="horis3.gif" BORDER=0></A><A HREF="thehelp.htm"><IMG SRC="horis4.gif" BORDER=0></A> </PRE>
(рис 7.4) Горизонтальное меню (рамки более не видны)
Пример 7.6. Теперь попробуем тем же способом реализовать вертикальное меню. При просмотре в некоторых браузерах сплошной вертикальной линии не получается, т.к. высота строки не равна высоте картинки. Подогнать эти параметры практически невозможно. Каждый пользователь настраивает браузер по своему вкусу.
<PRE> <IMG SRC=vert.gif WIDTH=27 HEIGHT=21 BORDER=0><A HREF="courses.htm"><IMG SRC="vert1.gif" WIDTH=103 HEIGHT=21 BORDER=0></A> <IMG SRC=vert.gif WIDTH=27 HEIGHT=21 BORDER=0><A HREF="setting.htm"><IMG SRC="vert2.gif" WIDTH=103 HEIGHT=21 BORDER=0></A> <!-- далее аналогично для vert3.gif и vert4.gif --> </PRE>
(рис 7.5) Вертикальное меню (линия не сплошная)Пример 7.7. Решение заключается в использовании (вместо контейнера < ) таблицы <TABLE> с нулевыми границами между ячейками:
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR>
<TD><IMG SRC=vert.gif WIDTH=27 HEIGHT=21 BORDER=0></TD>
<TD><A HREF="courses.htm"><IMG SRC="vert1.gif"
WIDTH=103 HEIGHT=21 BORDER=0></A></TD>
</TR>
<!-- далее аналогично для vert2, vert3, vert4.gif -->
</TABLE>
(рис 7.6) Вертикальное меню (линия сплошная)В данном случае все картинки удается сшить без пропусков и тем самым достичь непрерывности навигационного дерева. Пропуски устраняются путем применения атрибутов BORDER, CELLPADDING и CELLSPACING. Первый устраняет границы между ячейками и вокруг всей таблицы, второй устанавливает расстояние между ячейками равным 0 пикселов, третий устанавливает отступ между границей ячейки и элементом, помещенным в нее, в 0 пикселов.
Практически все, что было изложено до сих пор, касается вопросов построения одноуровневых меню. Поэтому в данном разделе мы постараемся привести более или менее реальные примеры таких меню. Графическое меню удобно тем, что автор может всегда достаточно точно расположить его компоненты на экране. Это, в свою очередь, позволяет и другие элементы страницы точнее располагать относительно элементов меню.
Пример 7.8. В данном примере мы воспользуемся этим для того, чтобы выделить тот пункт меню, над которым находится указатель мыши. Поскольку пункты меню прилегают друг к другу без просветов, то мы будем указывать стрелочкой тот пункт меню, который активен в данный момент.
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0> <TR ALIGN="center"> <TD> <IMG NAME=e1 SRC=empty.gif WIDTH=15 HEIGHT=8 BORDER=0> </TD> <!-- аналогично для e2, e3, e4 --> </TR> <TR> <TD><A HREF="javascript:void(0);" onMouseOver="document.e1.src='arrowdw.gif';" onMouseOut="document.e1.src='empty.gif';"> <IMG SRC="horis1.gif" BORDER="0"></A> </TD> <!-- аналогично для e2, e3, e4 --> </TR> </TABLE>
(рис 7.7) Горизонтальное меню (пункт указан стрелкой)Стрелочка бежит точно над тем элементом, на который указывает мышь.
Пример 7.9. Однако стоит заметить, что применение атрибута ALT у контейнера IMG и его дублирование в строке статуса является гораздо более информативным, чем добавление нового графического элемента. Правда, отображается содержание ALT с некоторой задержкой:
<PRE> <A HREF="courses.htm" onMouseOut="window.status='';" onMouseOver="window.status='Мои курсы';return true;"><IMG SRC="horis1.gif" BORDER=0 ALT="Мои курсы"></A><A HREF="setting.htm" onMouseOut="window.status='';" onMouseOver="window.status='Настройки';return true;"><IMG SRC="horis2.gif" BORDER=0 ALT="Настройки"></A><A HREF="baskets.htm" onMouseOut="window.status='';" onMouseOver="window.status='Корзина';return true;"><IMG SRC="horis3.gif" BORDER=0 ALT="Корзина"></A><A HREF="thehelp.htm" onMouseOut="window.status='';" onMouseOver="window.status='Помощь';return true;"><IMG SRC="horis4.gif" BORDER=0 ALT="Помощь"></A> </PRE>
(рис 7.8) Горизонтальное меню (атрибут ALT и поле статуса)Пример 7.10. Посмотрим теперь на реализацию вертикального меню, построенного на основе графических блоков текста:
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
<SCRIPT>
for(i=1; i<5; i++)
{ var
ileft = '<IMG SRC=block'+i+'.gif border=0>',
iright = '<IMG NAME=e'+i+' SRC=clear.gif border=0>',
isrc = 'document.e'+i+'.src',
alink = '<A HREF="javascript:void(0);" '+
'onMouseover="'+isrc+'=\'corner.gif\';" '+
'onMouseout="'+ isrc+'=\'clear.gif\';">';
document.write('<TR>'+
'<TD>'+ alink + ileft + '</A></TD>'+
'<TD>'+ alink + iright + '</A></TD>'+
'</TR>');
}
</SCRIPT>
</TABLE>
Здесь продемонстрировано типичное применение JavaScript - многократное генерирование похожих фрагментов HTML-кода с помощью цикла и метода document.write(). В данном примере с помощью цикла мы генерируем HTML-фрагмент следующего вида (каждый раз с разным номером вместо "1"):
<TR>
<TD><A onMouseover="document.e1.src='corner.gif';"
onMouseout="document.e1.src='clear.gif';"
HREF="javascript:void(0);"><IMG SRC=block1.gif border=0></A></TD>
<TD><A onMouseover="document.e1.src='corner.gif';"
onMouseout="document.e1.src='clear.gif';"
HREF="javascript:void(0);"><IMG NAME=e1 SRC=clear.gif border=0></A></TD>
</TR>
При движении мыши у соответствующего пункта меню, попавшего в фокус мыши, "отгибается уголок". В данном случае "уголок" - это самостоятельная картинка. Все уголки реализованы в правой колонке таблицы. Для того чтобы гипертекстовая ссылка срабатывала по обеим картинкам (тексту и "уголку"), применяются одинаковые контейнеры <A>, охватывающие каждую картинку.
(рис 7.9) Вертикальное меню (графические блоки текста)
В HTML нет стандартного способа реализации вложенных меню. Тем не менее за счет графики можно создать их подобие. При этом следует понимать, что место, на которое ложится графика, нельзя заполнить текстом.
Пример 7.11. В этом примере вложенное меню расположено справа от основного. Эффект вложенности достигается за счет изменения цвета (подпункты имеют цвет, отличный от цвета пунктов).
<SCRIPT>
function submenu(a)
{
with(document)
{
if(a==1)
{
item1.src="item_1_yes.gif"; // 1-й пункт активен
item2.src="item_2_no.gif"; // 2-й пункт неактивен
subi1.src="item_1_1.gif"; // 1-й пункт вложенного меню 1
subi2.src="item_1_2.gif"; // 2-й пункт вложенного меню 1
}
if(a==2)
{
item1.src="item_1_no.gif"; // 2-й пункт активен
item2.src="item_2_yes.gif"; // 1-й пункт неактивен
subi1.src="item_2_1.gif"; // 1-й пункт вложенного меню 2
subi2.src="item_2_2.gif"; // 2-й пункт вложенного меню 2
}
}
}
</SCRIPT>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=1>
<TR>
<TD><A HREF="javascript:void(0);" onMouseOver="submenu(1);">
<IMG BORDER=0 NAME=item1 SRC=item_1_yes.gif></A></TD>
<TD><IMG BORDER=0 NAME=subi1 SRC=item_1_1.gif></TD></TR>
<TR>
<TD><A HREF="javascript:void(0);" onMouseOver="submenu(2);">
<IMG BORDER=0 NAME=item2 SRC=item_2_no.gif></A></TD>
<TD><IMG BORDER=0 NAME=subi2 SRC=item_1_2.gif></TD></TR>
</TABLE>
(рис 7.10) Вложенное меню (пункт выделен цветом)Подчиненность меню можно подчеркнуть изменением его положения относительно основного меню (составьте соответствующий код самостоятельно):
(рис 7.11) Вложенное меню (пункт выделен сдвигом)В этом случае для продвижения меню вниз необходимо зарезервировать место при помощи невидимых или видимых картинок.
При использовании слоев можно создать настоящее выпадающее меню.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.