Выпадающее окошко с задержкой

Автор: Александр Головко Дата публикации: 10.08.2011

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

Казалось бы, что может быть проще и зачем тут вообще скрипты? Делаем окошко невидимым и просто показываем его по hover.

Но при таком типичном решении появляется подводный камень. Что будет, если посетитель сайта быстро проведет мышью вдоль ряда таких активных объектов? Или просто будет перемещать мышь по странице, совсем не рассчитывая на выскакивающий попап?

В обоих случаях он будет неприятно удивлен поведением сайта. Бестолковое мелькание попапов, это, наверное, не совсем то, что нам нужно.

Задача

Сделать так, чтобы всплывающее окошко появлялось не моментально, а с небольшой задержкой.

Решение

Вот тут на сцену и выходит скрипт. Я покажу решение с использованием моего любимого jQuery.

Допустим, у нас есть список изображений, а подсказки к ним заданы в тегах div:

<ul>
	<li><img src="images/pic200x150.jpg" width="200" height="150" alt=""/><div>Подпись</div></li>
	<li><img src="images/pic200x150-1.jpg" width="200" height="150" alt=""/><div>Подпись</div></li>
</ul>

Конечно, кто-нибудь может сказать, что красивее было бы избавиться от тега-подсказки в коде и генерировать ее, например, из атрибута data-title. Да, красивее. Но наша статья вовсе не про это. Для простоты, давай оставим все, как есть.

Итак, пишем CSS. Выпадающему окошку зададим абсолютное позиционирование и скроем его с помощью display: none.

		
li {
	position: relative;
}
li div {
	position: absolute;
	top: 120px;
	left: 20px;
	display: none;
}		

Теперь нам нужен скрипт, который будет показывать и скрывать окошко. Не забудь подключить jQuery.

Для начал покажу упрощенный вариант — без задержки. Используем событие hover. Тут все просто. При наведении мыши находим и показываем попап, при уходе мыши, скрываем его.

jQuery(document).ready(function(){

jQuery("li").hover(
  function () {
	jQuery(this).find("div").fadeIn();
  },
  function () {
   	jQuery("li div").fadeOut();
  }
);

});

Теперь давай сделаем задержку. Для этого воспользуемся замечательной js-функцией setTimeout.

jQuery(document).ready(function(){

var intervalID;
jQuery("li").hover(
  function () {
	var popup = jQuery(this).find("div");

	intervalID=setTimeout(
		function() {
		popup.fadeIn();
		}, 500);
	
  },
  function () {
   	jQuery("li div").fadeOut();
	clearInterval(intervalID);
  }
);

});

Демо-пример.

Проверено в:

  • IE 6-8
  • Firefox 3+
  • Opera 9.5-10.5
  • Safari 4
  • Chrome

Немного разъяснений по js

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

Как управлять задержкой?

Задержка определяется числовым параметром функции setTimeout. Я поставил 500мс (т.е. полсекунды):

intervalID=setTimeout(
	function() {
		popup.fadeIn();
	}, 500);

Зачем нам переменная intervalID?

Все просто. Когда мы наведем мышь на картинку, то setTimeout запустит счетчик. Даже после того, как мы уйдем с картинки, счетчик сработает и попап выскочит. Для того чтобы этого не случилось, мы сбрасываем счетчик с помощью функции clearInterval. А эта функция, в свою очередь, должна получить информацию, какой именно счетчик сбросить. Эта информация как раз и хранится в intervalID.

Зачем нужен var popup?

Действительно, может показаться, что проще написать:

…
jQuery("li").hover(
  function () {
	intervalID=setTimeout(
		function() {
		jQuery(this).find("div").fadeIn();
		}, 500);
  },
…

…и выбросить лишнюю строку и переменную.

Но такая запись не сработает, потому, что внутри setTimeout конструкция jQuery(this) уже не будет указывать на элемент li, на который мы навели курсор. Поэтому я предпочел найти попап заранее, до входа в счетчик и сохранить его в переменной.

Если остались еще какие-то вопросы по этому поводу — добро пожаловать в комментарии.