Добро пожаловать на портал вебмастеров WebmastersBY
Веб-программирование

Пишем скрипт обратного отсчета на jQuery

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

Пишем скрипт обратного отсчета на jQuery

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

Примечание: плагин также доступен на Github.

Итак, давайте начнем с разметки!

HTML

Мы создадим пустой элемент с id "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 для двух цифр для каждой единицы времени (дни, часы, минуты и секунды), это означает, что вы сможете отсчитывать даты не более чем на 99 дней (но вы, вероятно, не будете использовать таймер для таких далеких дат в любом случае, это будет странно).

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

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

Но как эта разметка генерируется?

JQuery

Прежде всего, давайте напишем две вспомогательные функции, используемые в плагине:

  • init генерирует разметку, которую вы видели выше;
  • switchDigit задает позицию span-элементам и анимирует цифры внутри них.

Разделение функциональности на отдельные функции позволяет нам держать чистым код плагина.

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 = $('<div>',{
        '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');
    });
}

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

Плагин готов! Вот как его использовать (как показано в демо):

assets/js/script.js

$(function(){

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

    if ((new Date()) > ts) {
        // The new year is here! Count towards something else.
        // Notice the *1000 at the end - time must be in milliseconds
        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 + " дн." + ( days==1 ? '':'s' ) + ", ";
            message += hours + " час." + ( hours==1 ? '':'s' ) + ", ";
            message += minutes + " мин." + ( minutes==1 ? '':'s' ) + " и ";
            message += seconds + " сек." + ( seconds==1 ? '':'s' ) + " <br />";

            if (newYear) {
                message += "осталось до Нового Года!";
            }
            else {
                message += "осталось от текущего момента до окончания 10 дней!";
            }

            note.html(message);
        }
    });

});

Отлично! Теперь давайте перейдем к основной части плагина. Наш плагин должен принять объект с параметрами для лучшего конфигурирования - timestamp периода на который мы создаем отсчет, и функцию обратного вызова, выполняемую при каждом вызове функции tick и передающую оставшееся время. Для краткости, я опустил упомянутые выше функции.

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

        // вызов callback функции
        options.callback(d, h, m, s);

        // Настраиваем вызов этой функции каждую секунду
        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;
 };

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

Лучше всего в данном примере то, что он не использует изображения, внешний вид создается при помощи только CSS. Поэтому увеличение или уменьшение размера шрифта не создаст вам дополнительных проблем, как это могло бы быть с изображениями, и вам нужно всего лишь объявить display:none, чтобы скрыть цифры в которых вы не нуждаетесь.

Комментарии 0

Новый комментарий

Имя:
Для редактирования комментария осталось 10 минут
Комментарии отсутствуют