Таймер обратного отсчета на jQuery

11.12.2012


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

В данном уроке мы построим плагин jQuery для вывода таймера обратного отсчета. Он будет выводить количество оставшихся дней, часов, минут и секунд до определенного момента. Анимированное обновление счетчика совершается каждую секунду.

HTML


Плагин имеет имя “countdown” (в переводе на русский язык — «обратный отсчет»). Вызванный для пустого элемента, плагин будет заполнять его кодом HTML, необходимым для формирования дисплея таймера. Больше не надо ничего делать, только выбрать нужный элемент, в котором будет отображаться время.

Генерируемая разметка

<div id="countdown" class="countdownHolder">
	<span class="countDays">
		<span class="position">
			<span class="digit static"></span>
		</span>
		<span class="position">
			<span class="digit static"></span>
		</span>
	</span>

	<span class="countDiv countDiv0"></span>

	<span class="countHours">
		<span class="position">
			<span class="digit static"></span>
		</span>
		<span class="position">
			<span class="digit static"></span>
		</span>
	</span>

	<span class="countDiv countDiv1"></span>

	<span class="countMinutes">
		<span class="position">
			<span class="digit static"></span>
		</span>
		<span class="position">
			<span class="digit static"></span>
		</span>
	</span>

	<span class="countDiv countDiv2"></span>

	<span class="countSeconds">
		<span class="position">
			<span class="digit static"></span>
		</span>
		<span class="position">
			<span class="digit static"></span>
		</span>
	</span>

	<span class="countDiv countDiv3"></span>
</div>

В выше приведённом примере плагин вызван для элемента div с идентификатором countdown. Плагин добавляет ему класс countdownHolder (поэтому несколько стилей применяются к элементу с помощью кода CSS).

Рассмотрим разметку для цифр. Существует два элемента span с классом digit для каждой единицы времени (дни, часы, минуты и секунды), что налагает ограничения по обратному отсчету количества дней (не более 99).

Статический класс определяет для цифр градиентный фон и тени. При анимации данный класс удаляется, и CSS3 работает без замедления. Цифры объединены в группы, поэтому легко изменить стили для них. Например, добавление свойства font-size к классу .countDays будет влиять на обе цифры дня.

Элемент span .countDiv является разделителем между единицами времени. Двоеточие формируется с помощью псевдо элементов :before/:after.

А как генерируется разметка?

jQuery


Сначала сделаем вспомогательные функции, которые используются в плагине:

init — генерирует разметку, которая приведена выше;
switchDigit — получает элемент span .position и анимирует цифры внутри него.
Выделим данный функционал отдельно, чтобы можно было рассматривать код плагина без помех.

assets/countdown/jquery.countdown.js

function init(elem, options){
	elem.addClass('countdownHolder');

	// Создаем разметку внутри контейнера
	$.each(['Days','Hours','Minutes','Seconds'],function(i){
		$('<span class="count'+this+'">').html(
			'<span class="position">\
				<span class="digit static">0</span>\
			</span>\
			<span class="position">\
				<span class="digit static">0</span>\
			</span>'
		).appendTo(elem);

		if(this!="Seconds"){
			elem.append('<span class="countDiv countDiv'+i+'"></span>');
		}
	});

}

// Создаем анимированный переход между двумя цифрами
function switchDigit(position,number){

	var digit = position.find('.digit')

	if(digit.is(':animated')){
		return false;
	}

	if(position.data('digit') == number){
		// Мы уже вывели данную цифру
		return false;
	}

	position.data('digit', number);

	var replacement = $('<span>',{
		'class':'digit',
		css:{
			top:'-2.1em',
			opacity:0
		},
		html:number
	});

	// Класс .static добавляется, когда завершается анимация.
	// Выполнение идет более плавно.

	digit
		.before(replacement)
		.removeClass('static')
		.animate({top:'2.5em',opacity:0},'fast',function(){
			digit.remove();
		})

	replacement
		.delay(100)
		.animate({top:0,opacity:1},'fast',function(){
			replacement.addClass('static');
		});
}

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

assets/countdown/jquery.countdown.js

(function($){

	// Количество секунд в каждом временном отрезке
	var days	= 24*60*60,
		hours	= 60*60,
		minutes	= 60;

	// Создаем плагин
	$.fn.countdown = function(prop){

		var options = $.extend({
			callback	: function(){},
			timestamp	: 0
		},prop);

		var left, d, h, m, s, positions;

		// инициализируем плагин
		init(this, options);

		positions = this.find('.position');

		(function tick(){

			// Осталось времени
			left = Math.floor((options.timestamp - (new Date())) / 1000);

			if(left < 0){
				left = 0;
			}

			// Осталось дней
			d = Math.floor(left / days);
			updateDuo(0, 1, d);
			left -= d*days;

			// Осталось часов
			h = Math.floor(left / hours);
			updateDuo(2, 3, h);
			left -= h*hours;

			// Осталось минут
			m = Math.floor(left / minutes);
			updateDuo(4, 5, m);
			left -= m*minutes;

			// Осталось секунд
			s = left;
			updateDuo(6, 7, s);

			// Вызываем возвратную функцию пользователя
			options.callback(d, h, m, s);

			// Планируем следующий вызов данной функции через 1 секунду
			setTimeout(tick, 1000);
		})();

		// Данная функция обновляет две цифоровые позиции за один раз
		function updateDuo(minor,major,value){
			switchDigit(positions.eq(minor),Math.floor(value/10)%10);
			switchDigit(positions.eq(major),value%10);
		}

		return this;
	};

	// Здесь размещаются две вспомогательные функции

})(jQuery);

Функция tick вызывает саму себя (рекурсия) каждую секунду. В ней мы вычисляем время между заданной точкой и текущим значением. Функция updateDuo затем обновляет цифры в соответствии с полученными данными.

Плагин готов! Теперь рассмотрим пример его использования (демонстрационная страница):

assets/js/script.js

$(function(){

	var note = $('#note'),
		ts = new Date(2012, 0, 1),
		newYear = true;

	if((new Date()) > ts){
		// Задаем точку отсчета для примера. Пусть будет очередной Новый год или дата через 10 дней.
		// Обратите внимание на *1000 в конце - время должно задаваться в миллисекундах
		ts = (new Date()).getTime() + 10*24*60*60*1000;
		newYear = false;
	}

	$('#countdown').countdown({
		timestamp	: ts,
		callback	: function(days, hours, minutes, seconds){

			var message = "";

			message += "Дней: " + days +", ";
			message += "часов: " + hours + ", ";
			message += "минут: " + minutes + " и ";
			message += "секунд: " + seconds + " <br />";

			if(newYear){
				message += "осталось до Нового года!";
			}
			else {
				message += "осталось до момента через 10 дней!";
			}

			note.html(message);
		}
	});

});

Конечно, чтобы демонстрация заработала, нужно подключить файлы CSS и JavaScript из папки плагина к странице.

Заключение

Плагин можно использовать на страницах с информацией о каком-либо событии. Основными его преимуществом является полная реализация на CSS без изображений. Увеличение или уменьшение размера шрифта позволяет выделить нужные единицы времени. А для отключения ненужных единиц надо использовать свойство display:none в соответствующем классе.

Источник урока: ruseller.com


  

Другие темы:

Создаем свою CMS на PHP и MySQL. Часть 1
Видеокурс ДИРЕКТ ТРАФИК
ФИШКИ ПРИБЫЛЬНОГО ТРАФИКА С ЯНДЕКС ДИРЕКТ
Курс по фреймворку CakePHP