Статьи

Наведите курсор мыши на изображения

Одним из самых популярных «вау» пунктов, который появляется во всей всемирной паутине, является наведение мыши. В простейшей форме указатель мыши — это некоторая часть веб-страницы, которая вызывает изменение отображения страницы, когда мышь пользователя проходит над ней. Все больше и больше творческих применений для наведения мыши появляются постоянно, от предоставления визуальных подсказок к значению ссылок на странице, до добавления полных, всплывающих , каскадных систем меню в DHTML (хороший пример см. В моем скрипте всплывающего меню это).

Впервые использование мыши стало технически возможным с выпуском Netscape Navigator 2.0, который включал новый язык сценариев под названием JavaScript. Идея состояла в том, чтобы позволить Интернету впервые превзойти базовую функциональность HTML. С помощью JavaScript веб-разработчики могли делать больше, чем просто переходить на новое место, когда пользователь нажимал на гипертекстовую ссылку — они могли фактически изменять содержимое загруженной в данный момент страницы. Когда Microsoft выпустила свой собственный веб-браузер, Microsoft Internet Explorer 3.0, они включили свой собственный вариант темы — JScript. Недавно Microsoft и Netscape договорились установить независимый от производителя стандарт, который разрабатывается Европейской ассоциацией производителей компьютеров под названием ECMAscript.

Поскольку стандарты в этой области сходятся, использование сценариев в Интернете становится все более возможным. Рост популярности мыши с использованием сценариев (в отличие от сравнительно медленных и неуклюжих реализаций Java, которые были популярны в течение короткого времени) является свидетельством полезности JavaScript и его родства.

Объект изображения

Строго говоря, вам не нужно знать JavaScript для понимания этой статьи, так как все объясняется с нуля. Однако, если у вас не было большого опыта программирования и вы вообще не знаете JavaScript, вы можете прочитать JavaScript 101 SitePoint, если он действительно начинает выглядеть так, будто я пишу по-гречески.

В большинстве случаев JavaScript является объектно-ориентированным языком, а это означает, что в мире JavaScript все является объектом. Окно браузера — это объект (называемый window ), веб-страница — это объект ( document ), а изображения на веб-странице — сами по себе объекты. Приятно то, что у объектов есть свойства, которые вы можете изменить.

Если вы знакомы с основами HTML (см. Наш учебник по HTML, если вы не знакомы), вы привыкнете к концепции, что вы можете создать объект изображения на веб-странице с помощью <IMG> :

 <IMG SRC="imagefile.gif" WIDTH="75" HEIGHT="40"> 

Теперь, не зная этого, при вводе этого текста вы автоматически создаете объект image JavaScript, который позволит вам позже изменить его свойства, если хотите. Это именно то, что мы хотим сделать, чтобы создать указатель мыши. Когда мышь перемещается по изображению, мы хотим изменить то, как изображение выглядит, и то, как изображение выглядит, является свойством объекта image .

Чтобы упростить обращение к этому конкретному объекту image позже, мы можем присвоить ему name . Это довольно легко сделать, и нам просто нужно добавить атрибут NAME в наш <IMG> .

 <IMG SRC="imagefile.gif" NAME="myimage" WIDTH="75" HEIGHT="40"> 

Теперь наш объект image называется « myimage » и может называться таковым. На данный момент стоит отметить, что JavaScript в значительной степени чувствителен к регистру. Другими словами, наше изображение с именем « myimage » не может называться « MYIMAGE » или « MyImage ».

Я сказал, что объекты в JavaScript имеют свойства, которые мы можем изменить. Мы можем установить свойство нашего объекта « myimage » с помощью следующего общего оператора JavaScript:

 document.images["myimage"].property = newvalue; 

Где property — это имя свойства, которое вы хотите изменить, а newvalue — это новое значение, которое вы ему присваиваете. Эту строку можно прочитать:

«В текущем document на image под названием« myimage »установите для property значение newvalue

Теперь я уверен, что вам не терпится узнать, как применить это к скромному наведению мыши. При наведении курсора мыши мы меняем image отображаемое объектом изображения. Как и в HTML, где мы используем атрибут SRC <IMG> для указания URL-адреса файла изображения, которое мы хотим отобразить, в JavaScript мы устанавливаем свойство src объекта image в URL-адрес файла изображения, который мы хотим это для отображения.

Используя общий оператор JavaScript, который я показал вам выше, он написан просто:

 document.images["myimage"].src = "newimage.gif"; 

Как работают мыши

Теперь, когда вы знаете, как изменить внешний вид изображения с помощью JavaScript, нам нужно выяснить, как это сделать, когда пользователь наводит курсор на изображение. Кроме того, нам нужно знать, как переключать его обратно, когда мышь пользователя больше не находится над изображением. Функция JavaScript, которая позволяет нам это делать, называется обработчиками событий.

Обработчики событий можно рассматривать как «триггеры», которые вызывают события, когда выполняется определенное условие. Два обработчика событий, которые нас интересуют, когда речь идет о Mouseovers, это onMouseOver и onMouseOut . Они позволяют вам определять определенные фрагменты JavaScript, которые будут запускаться всякий раз, когда мышь пользователя наводится или выходит из заданного HTML-элемента.

Хотя спецификация HTML 4.01 говорит о том, что мы должны иметь возможность определять обработчики событий onMouseOver и onMouseOut для любого элемента HTML, Netscape Navigator немного <A HREF> предоставляя только эту возможность для тега ссылки привязки ( <A HREF> ). Это означает, что Netscape может обнаруживать только перемещение мыши по гиперссылкам, и, если мы хотим сделать Mouseover, элемент, «чувствительный» к мыши, должен быть ссылкой. Это не слишком большая проблема, если мы хотим сделать наведение мышью, которое также не является ссылкой, потому что мы можем легко создать «ссылку в никуда» вокруг нашего изображения следующим образом:

 <A HREF="javascript:void(0)"><IMG SRC="imagefile.gif"  NAME="myimage" WIDTH=75 HEIGHT=40 BORDER=0></A> 

Это создает ссылку, которая ничего не делает (аннулируется) при нажатии. Если вы хотите, чтобы он ссылался на что-то, просто вставьте свой URL вместо javascript:void(0) . Чтобы добавить наши обработчики событий, достаточно просто вставить их в качестве атрибутов в тег <A HREF> :

 <A HREF="javascript:void(0)" onMouseOver="overmyimage()"  onMouseOut="outmyimage()"><IMG SRC="imagefile.gif" NAME="myimage"  WIDTH=75 HEIGHT=40 BORDER=0></A> 

В приведенном выше overmyimage() и outmyimage() — это функции JavaScript, которые обрабатывают изменение изображения между состояниями « outmyimage() » и «выключено». Функция — это фрагмент JavaScript, который был отложен для «запуска» позднее. В большинстве случаев функции определены в заголовке вашего HTML-файла (между тегами <HEAD> и </HEAD> ). Наша overmyimage() будет выглядеть примерно так:

 <HEAD>  <SCRIPT LANGUAGE="JavaScript">  <!-- Hide from older browsers   function overmyimage() {  ... code here ...  }   // End script hiding -->  </SCRIPT>  </HEAD> 

Мы вставили бы код, который должен запускаться всякий раз, когда эта функция вызывается (срабатывает) в месте, которое я указал.

Теперь, вооружившись базовыми знаниями об объекте изображения, обработчиках событий и функциях, мы теперь готовы к созданию…

Наша первая мышь

Если вы внимательно следите и полностью понимаете элементы, которые я рассмотрел до сих пор, их сборка в работающую мышь должна быть почти очевидной. Если вы немного смущены, не беспокойтесь — я проведу вас шаг за шагом в этом разделе, чтобы все стало ясно.

Во-первых, давайте начнем с создания нашего имиджа. Он будет иметь ширину 70 пикселей и высоту 30 пикселей, а имя файла для «неактивного» изображения будет « off.gif ». Мы делаем это так же, как обычно, используя HTML- <IMG> . Мы также будем использовать атрибут NAME чтобы присвоить ему имя « my1stMouseOver ».

 <IMG SRC="off.gif" WIDTH=70 HEIGHT=30 BORDER=0 NAME="my1stMouseOver"> 

Теперь мы добавим «ссылку в никуда» вокруг нашего изображения, чтобы мы могли подключать onMouseOver событий onMouseOver и onMouseOut , чтобы запускать функции JavaScript, которые «активируют» и «деактивируют» изображение. Соответственно, мы будем вызывать эти функции activate() и deactivate() .

 <A HREF="javascript:void(0)" onMouseOver="activate()"  onMouseOut="deactivate()"><IMG SRC="off.gif" WIDTH=70  HEIGHT=30 BORDER=0 NAME="my1stMouseOver"></A> 

Теперь осталось только написать функции JavaScript, activate() и deactivate() . Функция activate() изменит свойство src объекта « my1stMouseOver » на «активный» файл изображения, который мы назовем « on.gif ».

 function activate() {  document.images["my1stMouseOver"].src = "on.gif";  } 

Аналогично, функция deactivate() изменит свойство src объекта « my1stMouseOver » обратно на «неактивный» файл изображения « off.gif ».

 function deactivate() {  document.images["my1stMouseOver"].src = "off.gif";  } 

Вот и все! Теперь мы создали изображение, которое отображает « off.gif », за исключением случаев, когда пользователь off.gif на него указатель мыши, и в этот момент оно меняется на « on.gif ». Когда пользователь снова убирает мышь, он возвращается к отображению « off.gif ».

В следующих разделах мы возьмем основную мышь, созданную в предыдущем разделе, и добавим пару наворотов, которые улучшат ее расширяемость и производительность. В целом, это хорошие навыки, чтобы знать, собираетесь ли вы серьезно использовать указатели мыши на страницах, которые вы разрабатываете.

Функции обмена

В нашем основном наведении мыши мы использовали один <IMG> и две функции JavaScript, чтобы получить искомый эффект, но на странице с 5 указателями мыши это означало бы необходимость написать 10 различных функций (не говоря уже о том, чтобы придумать 10 разные имена для них!). Что если бы был способ использовать одинаковые две функции для всех указателей мыши на вашей странице?

Оказывается, это на удивление легко сделать. Во-первых, мы должны создать переменные JavaScript, которые содержат имя файла каждого изображения при наведении и выключении мыши. Если, например, мы создали страницу с тремя тегами <IMG> которые мы хотим сделать наведением мыши, и мы назвали эти изображения « first », « second » и « third », используя атрибут NAME <IMG> тег, мы бы создали переменные с именами формы name _on и name _off , например:

 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"; 

Следующее, что нам нужно сделать, это настроить onMouseOut событий onMouseOver и onMouseOut чтобы передать имя изображения для изменения нашим функциям. Например, код для нашего «второго» Mouseover будет выглядеть так:

 <A HREF="second.html" onMouseOver="activate('second')"  onMouseOut="deactivate('second')"><IMG SRC="image2off.gif"  WIDTH=70 HEIGHT=30 BORDER=0 NAME="second"></A> 

Обратите внимание, что аргумент (текст, который будет передан функции) заключен в одинарные кавычки ( ' ). Это сделано для того, чтобы они не мешали двойным кавычкам ( " ), окружающим обработчик событий.

Передавая имя изображения, подлежащего изменению, нашим функциям activate и deactivate , мы даем им возможность узнать, какое изображение нужно изменить при запуске. Таким образом, нам удается разделить две функции между столько мышью, сколько мы хотим. Осталось только изменить эти функции, чтобы получить это имя изображения, и использовать его для изменения правильного изображения.

Код для наших новых функций будет выглядеть так:

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

Поместив слово imgName в круглые скобки, которые следуют за именем функций, мы говорим им принять значение, которое им передается (в данном случае имя изменяемого изображения), и вставить его в переменную с именем imgName пока мы не закончим обработку функции. Затем мы используем эту переменную в двух местах. Сначала мы используем его, чтобы указать, какой объект images[imgName] свойство src мы хотим изменить ( images[imgName] ). Во-вторых, мы используем его для ссылки на переменную, которая содержит правильное имя файла. Это делается с помощью встроенной функции eval(...) .

 eval( imgName + "_on" ) 

Все, что это делает, — принимает значение переменной imgName , imgName его вместе с фрагментом текста « _on » и затем оценивает результат, как если бы это был обычный фрагмент кода JavaScript. Чтобы сделать это как можно более понятным, давайте рассмотрим, что произойдет, если onMouseOver события onMouseOver запущен на изображении с именем « third ».

Когда запускается обработчик события onMouseOver, он запускает функцию активации и передает ему имя изображения — « third ». Функция принимает этот аргумент и помещает « third » везде, где появляется переменная imgName .

 function activate("third") {  document.images["third"].src = eval( "third" + "_on" );  } 

Встроенная функция eval(...) склеивает две строки, которые она имеет (как указано оператором « + »), а затем оценивает ее, как если бы это был обычный фрагмент JavaScript:

 document.images["third"].src = third_on; 

Теперь third_on — это имя переменной, содержащей имя файла «on» для «третьего» изображения, поэтому его значение подставляется в:

 document.images["third"].src = "image3on.gif"; 

И это все — у нас осталось выражение той же формы, которое мы использовали для основного наведения мыши, которое изменит свойство src "third" изображения на « image3on.gif »! Ключевым моментом было присвоение имен переменным, содержащим имена файлов, чтобы функция eval(...) могла придумать имя переменной, просто _on « _on » или « _off » к концу имени изображения.

Предварительная загрузка изображений

Большинство веб-браузеров в наши дни довольно умны. Когда они загружают что-то, они помещают это в кеш в вашей системе, где оно будет оставаться некоторое время для быстрого и легкого доступа в случае необходимости снова. Однако большинство браузеров недостаточно умны, чтобы загружать вещи раньше времени. В большинстве случаев это не большая проблема, но когда дело доходит до наведения мыши, это может быть неприглядной слабостью.

Когда пользователь наведет курсор на одну из ваших мышек, веб-браузер поймет, что ему нужно отобразить «включенное» изображение. Если этот пользователь впервые заходит на ваш сайт, скорее всего, изображение отсутствует в кэше и должно быть загружено с вашего сайта. Это приводит к задержке, которая часто может быть больше, чем требуется пользователю, чтобы отодвинуть мышь от наведения мыши, так как он никогда не видел ту красивую кнопку с подсветкой, которую вы планировали отобразить. Хуже того, если «включенное» изображение загружено только частично, пользователь может увидеть ужасное размытое пятно в месте того гладкого изображения, которое вы запланировали.

Как мы можем преодолеть эту проблему? Решение состоит в том, чтобы предварительно загрузить изображения, требуемые при наведении курсора, в кэш пользователя, чтобы мы могли быть уверены, что они доступны, прежде чем пытаться их отобразить. Чтобы сделать это, мы должны творчески использовать объект изображения JavaScript.

До сих пор мы создавали только графические объекты со стандартным <IMG> HTML <IMG> . Однако мы можем создавать их, используя только JavaScript. Такие только графические объекты JavaScript не отображаются на веб-странице, но они загружаются и кэшируются, и у них есть те же свойства, что и у объекта изображения, созданного с помощью HTML. Таким образом, стратегия заключается в создании только графических объектов JavaScript для каждого из файлов изображений, которые будут использоваться при наведении курсора мыши. Чтобы сделать это для нашего примера трех указателей мыши, использованных в предыдущем разделе, мы можем заменить наши объявления переменных следующими объявлениями изображений:

 var first_off = new Image();  first_off.src = "off1.gif";  var first_on = new Image();  first_on.src = "on1.gif";   var second_off = new Image();  second_off.src = "off2.gif";  var second_on = new Image();  second_on.src = "on2.gif";  var third_off = new Image();  third_off.src = "off3.gif";  var third_on = new Image();  third_on.src = "on3.gif"; 

Для каждого файла изображения мы создаем новый объект изображения, а затем устанавливаем для его атрибута src соответствующее имя файла. Устанавливая это свойство, браузер решает, что ему необходимо загрузить файл изображения, после чего он сохраняется в кэше для быстрого поиска, когда он фактически необходим для отображения. Мы соблюдаем то же соглашение об именах для объектов изображений, что и для переменных имени файла в предыдущем разделе.

Теперь осталось только настроить наши функции activate и deactivate (да, опять же ) так, чтобы они использовали значения свойств src объектов изображений только для JavaScript вместо значений переменных.

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

Наконец, мы можем сделать еще одну настройку, чтобы вдвойне убедиться, что пользователь никогда не увидит наполовину загруженное изображение. Хотя этот метод предварительной загрузки загружает изображения при наведении курсора заранее, пользователь все же может вызвать наведение мыши до того, как изображения будут полностью загружены. Чтобы избежать этого, мы добавили небольшой «клапан» в функции activate и deactivate :

 function activate(imgName) {  if ( eval(imgName + "_on.complete") ) {  document.images[imgName].src = eval( imgName + "_on.src" );  }  }   function deactivate(imgName) {  if ( eval(imgName + "_off.complete") ) {  document.images[imgName].src = eval( imgName + "_off.src" );  }  } 

Это использует другое свойство объекта изображения JavaScript. Мы уже знаем, что свойство src содержит URL файла изображения, которое оно представляет. Здесь мы используем свойство complete , которое имеет значение true если изображение завершило загрузку, и значение false если это не так. Эти недавно измененные версии activate и deactivate изменение отображаемого изображения только в том случае, если завершен только графический объект JavaScript, отвечающий за предварительную загрузку нового изображения.

Продвинутые Методы

Наконец, этот раздел покажет вам простой способ убедиться, что ваши страницы при наведении курсора мыши совместимы со старыми браузерами, а также полезный прием, предотвращающий замедление остальной части страницы при предварительной загрузке изображений при наведении курсора.

Совместимость браузера с обнаружением объектов

Теперь, когда вы знаете все о том, как сделать так, чтобы мыши хорошо работали, стоит потратить немного времени на то, чтобы научиться делать такие, которые не работают так же хорошо. Хотя указатели мыши того типа, который я описал до сих пор, будут работать согласованно во всех последних браузерах с поддержкой JavaScript (Netscape 3+, а также MSIE 4+), есть некоторые браузеры, которые поддерживают JavaScript, но не полностью поддерживают объект image .

Одним из таких браузеров является Microsoft Internet Explorer 3.0. Если бы мы загружали страницу, содержащую указатели мыши, с кодом, который я до сих пор использовал в MSIE 3.0, мы бы увидели много ужасных ошибок JavaScript. Поскольку в этом браузере мы не можем навести указатель мыши, по крайней мере мы можем избавиться от сообщений об ошибках.

Хотя существует несколько способов определения версии браузера пользователя в JavaScript и соответствующей реакции, такие методы могут иногда оказаться непредсказуемыми в условиях менее распространенных веб-браузеров. Кроме того, всякий раз, когда Netscape или Microsoft выпускают новую версию своего программного обеспечения для браузера, необходимо обновить любую страницу, использующую такие сценарии обнаружения браузера.

Гораздо более надежным и эффективным является малоизвестный метод, называемый обнаружением объектов. Идея состоит в том, что вместо определения версии браузера мы обнаруживаем функции, которые поддерживает браузер. Поскольку любой браузер, поддерживающий объект изображения, будет способен навести курсор мыши, нам нужно только определить, знает ли браузер, что такое объекты изображения, прежде чем мы сделаем что-нибудь, что требует их поддержки. Это делается с помощью простого оператора if:

 if (document.images) {  ... code here ...  } 

Который можно прочитать:

« If текущий document содержит images выполните следующие действия…»

Если мы добавим if (document.images) к функциям activate и deactivate и поместим один вокруг объявлений изображений, у нас появятся указатели мыши, которые тихо исчезают в браузерах, которые не поддерживают объект image .

Задержка загрузки изображения

Предварительная загрузка изображений — это хорошо, но что, если у вас есть 20 указателей мыши на данной странице? Вы действительно хотите, чтобы браузер загружал 20 изображений, прежде чем он даже начал загружать фактическое содержимое страницы? Обычно нет. onLoad способом решения этой onLoad является использование onLoad события onLoad тега <BODY> для запуска функции, которая загружает изображения при onLoad только после загрузки HTML-кода для страницы. Таким образом, все изображения, фактически отображаемые на странице, помещаются перед изображениями при наведении курсора в порядке загрузки.

Использование onLoad довольно просто:

 <BODY onLoad="loadImages()"> 

Все, что осталось, — это поместить предварительную загрузку изображений при loadImages() внутрь функции loadImages() .

 if (document.images) {  var first_off = new Image();  var first_on = new Image();   var second_off = new Image();  var second_on = new Image();   var third_off = new Image();  var third_on = new Image();  }   function loadImages() {  if (document.images) {  first_off.src = "off1.gif";  first_on.src = "on1.gif";   second_off.src = "off2.gif";  second_on.src = "on2.gif";   third_off.src = "off3.gif";  third_on.src = "on3.gif";  }  } 

Обязательно обратите внимание, что я оставил создание графических объектов только для JavaScript вне функции loadImages() . Это сделано по двум причинам. Во-первых, создание объектов не загружает никаких файлов: это делает только установка свойств src , поэтому оставление объявлений объектов вне функции не замедляет загрузку остальной части страницы. Во-вторых, объекты или переменные, созданные внутри функции, существуют только внутри этой функции. Если бы мы переместили создание объектов изображения внутри функции, они бы исчезли, как только функция закончила работать, и тогда функции activate и deactivate больше не могли бы их использовать.

Это оно! Теперь наши изображения при наведении курсора будут загружаться только тогда, когда сработает обработчик события onLoad тега <BODY> , и это происходит только после загрузки кода HTML для всей страницы и начала загрузки любых изображений на этой странице. Желательно это или нет, решать вам, но это может быть хорошей идеей в тех случаях, когда на странице много указателей мыши и их немедленная доступность не так важна.

В итоге

В этой статье я постарался представить полную картину техник, которые заставляют элементы веб-страницы реагировать на движения мыши пользователя. Я не только рассмотрел основы в терминах, которые, надеюсь, были доступны любому, имеющему элементарные знания в области веб-дизайна и общего программирования, но также затронул некоторые более сложные темы, которые могут оказаться полезными для более опытного веб-разработчика.

Более подробную информацию, связанную с этой статьей, можно найти по адресу: