Making a jQuery Countdown Timer

When building a coming soon or event page, you find yourself in search for a good way to display the remaining time. A countdown gives the feel of urgency, and combined with an email field will yield more signups for your newsletter.

Today we are going to build a neat jQuery plugin for displaying a countdown timer. It will show the remaining days, hours, minutes and seconds to your event, as well as an animated updates on every second.Note: the plugin is also available on Github.

Let’s start with the markup!

The HTML

We will give the plugin the creative name of “countdown”. Called on an empty element, it will fill it with the HTML that is needed for the countdown timer. You don’t need to do anything but choose the element in which you want to show it.

Generated markup

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

In the above example, the plugin has been originally called on a div with an id of countdown. The plugin has then added a countdownHolder class to it (so a few styles are applied to the element via CSS).

Inside is the markup for the digits. There are two digit spans for every time unit (days, hours, minutes and seconds), which means that you can count down towards a date that is no more than 99 days in the future (for such time frames you should probably not use the timer anyway, it would be discouraging).

The static class of the digits gives them their gradient background and box-shadow. When animated, this class is removed so that these CSS3 touches don’t slow down the animation. The digits are brought together in groups so you can easily style them. Adding a font-size declaration to .countDays, will affect the size of both day digits.


A jQuery Countdown Timer

The .countDiv spans are the dividers between the units. The colon is formed with :before/:after elements.

But how is this markup generated exactly?

The jQuery

First let’s write two helper functions used by the plugin:

  • init generates the markup you saw above;
  • switchDigit takes a .position span and animates the digits inside it;

Extracting this functionality as separate functions allows us to keep the plugin code clean.

assets/countdown/jquery.countdown.js

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

// Creating the markup inside the container
$.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>’);
}
});

}

// Creates an animated transition between the two numbers
function switchDigit(position,number){

var digit = position.find(‘.digit’)

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

if(position.data(‘digit’) == number){
// We are already showing this number
return false;
}

position.data(‘digit’, number);

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

// The .static class is added when the animation
// completes. This makes it run smoother.

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

Great! Now let’s move on with the plugin body. Our plugin must take an object with parameters for better configurability – a timestamp of the period we are counting towards, and a callback function, executed on every tick and passed the remaining time. For brevity, I’ve omitted the functions above from the code.

assets/countdown/jquery.countdown.js

(function($){

// Number of seconds in every time division
var days = 24*60*60,
hours = 60*60,
minutes = 60;

// Creating the plugin
$.fn.countdown = function(prop){

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

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

// Initialize the plugin
init(this, options);

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

(function tick(){

// Time left
left = Math.floor((options.timestamp - (new Date())) / 1000);

if(left &lt; 0){
left = 0;
}

// Number of days left
d = Math.floor(left / days);
updateDuo(0, 1, d);
left -= d*days;

// Number of hours left
h = Math.floor(left / hours);
updateDuo(2, 3, h);
left -= h*hours;

// Number of minutes left
m = Math.floor(left / minutes);
updateDuo(4, 5, m);
left -= m*minutes;

// Number of seconds left
s = left;
updateDuo(6, 7, s);

// Calling an optional user supplied callback
options.callback(d, h, m, s);

// Scheduling another call of this function in 1s
setTimeout(tick, 1000);
})();

// This function updates two digit positions at once
function updateDuo(minor,major,value){
switchDigit(positions.eq(minor),Math.floor(value/10)%10);
switchDigit(positions.eq(major),value%10);
}

return this;
};

/* The two helper functions go here */

The tick function calls itself every second. Inside it, we calculate the time difference between the given timestamp and the current date. The updateDuo function then updates the digits comprising the time unit.

The plugin is ready! Here is how to use it (as seen in the demo):

assets/js/script.js

$(function(){

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

if((new Date()) &gt; 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 + " day" + ( days==1 ? '':'s' ) + ", ";
message += hours + " hour" + ( hours==1 ? '':'s' ) + ", ";
message += minutes + " minute" + ( minutes==1 ? '':'s' ) + " and ";
message += seconds + " second" + ( seconds==1 ? '':'s' ) + " &lt;br /&gt;";

if(newYear){
message += "left until the new year!";
}
else {
message += "left to 10 days from now!";
}

note.html(message);
}
});

});

Of course, for this to work, you will have to include the css and js file from the countdown folder in your page.

Done!

You can use this script as the perfect addition to every launch page. The best thing about it is that it doesn’t use a single image, everything is done with CSS alone. Increasing or decreasing the font size will result in everything scaling nicely, and you only need a display:none declaration to hide the units you don’t need.

source: http://urly.us/cV

Leave a comment

Your email address will not be published.