Задача: Предварительная загрузка изображений
Исходник: Использование событий onMouseOver и onMouseOut, язык: javascript [code #587, hits: 8376]
аноним: Сергей [добавлен: 06.03.2009]
  1. Ссылка на архив с работами: http://content3.wuala.com/contents//index.html/Programming/JS/onMouseOut_Over.rar
Изображения как объекты
В объектной модели, используемой Javascript, объектами являются не только браузерное окно (window) или Web-страница (document), но и элементы, включенные в Web-документы, такие как изображения. Это означает, что каждый раз, когда программист использует в Web-документе тег <IMG>, он создает новый объект. Как и в случае других объектов, представление изображений в виде объектов дает возможность позже изменять некоторые свойства этих объектов.
Чтобы иметь возможность программно управлять свойствами объекта, объект должен получить имя, которое далее будет использоваться для ссылок на него.
В случае картинок именование объекта-изображения достигается включением в тег <IMG> атрибута NAME:
<IMG SRC="image.gif" NAME="myImage" WIDTH="20" HEIGHT="20">.
Так как Javascript учитывает регистры букв, то при обращении к объекту-изображению нужно строго придерживаться того, как было определено имя объекта. Это означает, что для ссылки на только что определенный объект, нельзя использовать имена, записанные как "MYIMAGE", "MyImage" и т.п.

Все изображения, включенные в Web-страницу, являются элементами коллекции images, являющейся одним из свойств объекта document. Элементы коллекции организованы в ассоциативный массив, поэтому для обращения к ним вместо числовых индексов используются имена. Например, для доступа к объекту-изображению myImage нужно применять следующий синтаксис:
document.images["myImage"].
У объектов-изображений имеется свойство src (см. спецификацию HTML 4), которое содержит URL графического файла, описывающего изображение. Для дальнейшего важно отметить, что это свойство объекта можно не только прочесть, но и изменить:
document.images["myImage"].src="newImage.gif"

Обработка событий onMouseOver и onMouseOut для изображений
Нынешняя спецификация HTML требует, чтобы обработка событий
onMouseOver — "курсор мыши наведен на картинку" и
onMouseOut — "курсор мыши вышел за пределы картинки"
поддерживалась всеми HTML-элементами, в том числе и изображениями.
Замечание.
Так как onMouseOver и onMouseOut являются атрибутами HTML-тегов, то регистры букв в их записи роли не играют. Поэтому не будет ошибкой писать названия этих атрибутов как onmouseover, onmouseout и т.п.
Для создания динамического эффекта смены картинки при "наезжании" на нее курсора мыши необходимо назначить (для соответствующего объекта) функцию-обработчик события onMouseOver. Аналогично, чтобы при выводе курсора за пределы картинки восстанавливалось старое изображение, необходимо назначить функцию-обработчик события onMouseOut.
В основном тексте веб-страницы, в теге <IMG> указывается файл изображения, соответствующего onMouseOut.
Замечание.
Браузер Netscape 4.x обеспечивает поддержку требуемых свойств только для гиперссылок (тег <A>). Поэтому обработчики, определенные непосредственно в теге <IMG>, работать не будут. Однако это проблема легко решается путем создания ссылки "никуда":
<A HREF="javascript:void(0)" onMouseOver="overFunc()"
onMouseOut="outFunc()"><IMG SRC="image.gif"
NAME="myImage" WIDTH=20 HEIGHT=20 BORDER=0></A>
Так как браузер в данном случае воспринимает изображение как гиперссылку, то, чтобы не появлялась рамка вокруг картинки, в теге <IMG> необходимо задать атрибут BORDER равным нулю.
Этот прием должен применяться всегда, так как он обеспечивает межбраузерную совместимость.
Подготовка обработки событий onMouseOver и onMouseOut
для нескольких изображений
В задании 2 для создания эффекта изменения картинки потребовалось написать две функции. Если подобный эффект должен быть предусмотрен на веб-странице для нескольких изображений, то потребуется писать по две функции на каждое изображение, что неудобно. Для управления замещением нескольких картинок с помощью одной функции используется специальный набор приемов.
1. Для каждой пары изображений создаются переменные, хранящие имена файлов изображений, имена которых различаются только окончаниями: "_on" — над, и "_off" — вне).
Например, если основу идентификаторов для пар картинок составляют имена first, second и third, то необходимо определить следующие переменные:
var first_off = "image1off.gif";
var first_on = "image1on.gif";
var second_off = "image2off.gif";
var second_on = "image2on.gif";
var third_off = "image3off.gif";
var third_on = "image3on.gif";
Такой подбор имен нужен, чтобы упростить написание универсальных обработчиков.

2. Далее, так как для обработки событий onMouseOver и onMouseOut всех изображений будут использоваться одни и те же две функции, то этим функциям необходимо передавать некоторый признак, который позволит обработчикам определять, какое из изображений сгенерировало данное событие.
Этим признаками служат имена, взятые за основу идентификаторов файлов изображений (first, second и third).

<A HREF="javascript:void(0)" onMouseOver="mouseOn('first')"
onMouseOut="mouseOut('first')"> <IMG SRC="image1off.gif"
WIDTH=70 HEIGHT=30 BORDER=0 NAME="first"></A>

Функции-обработчики имеют вид:
function mouseOn(imgName) {
document.images[imgName].src = eval( imgName + "_on" );
}

function mouseOut(imgName) {
document.images[imgName].src = eval( imgName + "_off" );
}

Встроенная функция eval в правых частях превращает символьные строки, полученные в результате конкатенации, в имена переменных. Например, если вызывается обработчик mouseOn("third"), то в нем будет выполнено следующее присваивание:
document.images["third"].src = third_on;
т.е. в веб-страницу будет подставлено изображение "image3on.gif".

Предварительная загрузка изображений
Современные браузеры ведут себя достаточно продуманно. Когда они что-то загружают, то помещают это в кэш, где скачанная информация хранится некоторое время, чтобы ее можно было быстро получить еще раз без обращения к сети. Однако браузеры не в состоянии определить самостоятельно, какая информация может вскоре потребоваться. В большинстве случаев это не создает проблем. Но когда вопрос касается смены изображений при событии onMouseOver, то даже небольшое время, потраченное на скачивание второй картинки, может свести к нулю весь эффект. К моменту, когда изображение будет загружено, пользователь скорее всего уже уберет курсор и произойдет событие onMouseOut, возвращающее первую картинку. Еще хуже, если смена изображения произойдет, когда картинка загружена только частично, так как пользователь увидит неприглядные обрывки изображений.
Проблема решается с помощью предварительной загрузки всех изображений в кэш, откуда доступ к ним будет максимально быстрым. Чтобы сделать это, необходимо использовать механизм создания объектов изображений средствами Javascript (а не HTML, как ранее).
Для каждого файла изображения (и _on, и _off) создается новый объект типа Image, а затем свойству src этого объекта присваивается имя соответствующего файла. Как обычно в объектных языках, новые объекты в Javascript создаются с помощью операции new. Например,
var first_off = new Image(); // создаем новый объект
first_off.src = "off1.gif"; // загружаем файл и связываем его с объектом
Очевидно, что функции способ создания объекта не должен влиять на методы работы с этим объектом. Поэтому вносить большие изменения в функции-обработчики mouseOn/Off не придется. Необходимо учесть только, что в правой части операторов присваиваний вместо переменных необходимо использовать свойства src объектов-изображений:
document.images[imgName].src = eval( imgName + "_on.src" )
Однако при быстрых действиях пользователя осталась еще вероятность появления на странице частично загруженного изображения. Чтобы избежать этого, и в одной, и в другой функции-обработчике присваивания новых изображений (т.е. их смену) нужно разрешать только когда соответствующая картинка полностью загружена.
У объектов Image имеется специальное свойство complete (завершено), которое принимает значение true только тогда, когда картинка полностью загружена. Это дает возможность запрещать смену изображения тогда, когда оно еще полностью не получено. Например,
if ( eval(imgName + "_on.complete") )
document.images[imgName].src = eval( imgName + "_on.src" );
Замечание.
Браузер Netscape 4.x при проверке свойства complete всегда возвращает true.

Отложенная загрузка изображений
Предварительная загрузка изображений для своих целей работает хорошо, но если на странице таких изображений много, то это потребует значительного времени. Очевидно, что задерживать загрузку основного содержания страницы до тех пор, пока будут загружены все изображения, не является правильным решением. Более рационально поступить наоборот: загрузить основное содержание, а потом уже изображения.
Для этой цели удобно воспользоваться событием onLoad (тег body), которое возникает, когда HTML-код страницы полностью загружен. Поэтому, если загрузка изображений предусмотрена в обработчике onLoad, то она будет происходить после загрузки основного содержания. Используется следующая техника.
На глобальном уровне скрипта создаются объекты-изображения (чтобы сделать их видимыми отовсюду):
var first_off = new Image();
var first_on = new Image();
Во-вторых, подготавливается функция-обработчик события onLoad (назовем ее, например, loadImages()). В этой функции предусмотрена только загрузка файлов изображений, которая происходит в момент присваивания имен файлов свойствам src объектов:
first_off.src = "off1.gif";
first_on.src = "on1.gif";
и так для всех объектов.

+добавить реализацию