function f() { var i=5; k=7; } f(); alert(k); В примере выдается результат k=7, однако, хоть переменная и не объявлена, она внутри функции, т.е. локальная и не должна быть видима, или вторая и последующие все-таки становятся глобальными? |
Программируем графику
Объект Image
Наиболее зрелищные эффекты при программировании на 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
Свойства src и lowSrc определяют URL изображения, которое монтируется внутрь документа. При этом lowSrc определяет временное изображение, обычно маленькое, которое отображается, пока загружается основное изображение, чей URL указывается в атрибуте SRC контейнера IMG. Свойство src принимает значение атрибута SRC контейнера IMG. Программист может изменять значения и src, и lowSrc. В предыдущем примере мы можем изменить значение src следующим образом:
document.picname.src='river.gif';
Как видно из этого примера, существует возможность модифицировать картинку за счет изменения значения свойства src встроенного объекта Image. Если вы в первый раз просматриваете данную страницу (т.е. картинки не закешированы браузером), то постепенное изменение картинки будет заметно (конечно, при низкой скорости подключения к Internet; а также это зависит от браузера, который может загрузить картинку, а только потом вывести ее целиком на страницу). Как ускорить это изменение, мы рассмотрим в следующем разделе.
Изменение картинки
Изменить картинку можно, только присвоив свойству src встроенного объекта Image новое значение. Выше было показано, как это делается в простейшем случае. Очевидно, что медленная перезагрузка картинки с сервера не позволяет реализовать быстрое листание. Попробуем решить эту проблему. (Последующее в этом параграфе писалось в 2001-2002 годах, когда время подгрузки графики было значительным, чтобы можно было наблюдать описываемые ниже эффекты от оптимизации. - Прим.ред.).
Пример 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. А вот с левой частью не все так просто. На помощь приходит функция eval("выражение"), которая воспринимает переданное ей выражение как программу JavaScript и выполняет все содержащиеся в ней операторы. С ее помощью решить нашу проблему легко - мы составляем нужную строчку, а затем отдаем ее на выполнение:
for(i=0;i<32;i++) eval("document.m" +i+ ".src = mono[" +i+ "].src;");