If there is one thing I don't like doing, it's doing the same thing twice or even more! So I was building an application on the side where I need to have a listing that performs a simple countdown. At this point, I've been lazy and just have it counting down the seconds, but this example would be really easy to update to put a proper countdown of days, hours, minutes, and seconds and heck if you get really adventurous even weeks, months, and years!
In this example, I have a listing of items. Each item has a separate countdown timer associated with it that can be different. This will be some simple HTML code:
<div id="items">
<div>
<h1>Item Title 1</h1>
<h2>Available in: <span id="item_1"></span><span id="item_done_1">Ready!</span></h2>
</div>
<div>
<h1>Item Title 2</h1>
<h2>Available in: <span id="item_2"></span><span id="item_done_2">Ready!</span></h2>
</div>
<div>
<h1>Item Title 3</h1>
<h2>Available in: <span id="item_3"></span><span id="item_done_3">Ready!</span></h2>
</div>
</div>
Now that we have three items with a spot each to indicate when it is available, JavaScript code is required to create, display, and update the counter
. The first part of the code below will create the counter
objects.
<script>
var currentTime = new Date();
currentTime = currentTime.getTime();
var counter_1 = new Object();
counter_1.time = currentTime;
counter_1.reward_time = 10;
counter_1.finished = '#item_done_1';
counter_1.id = '#item_1';
AddCounter(counter_1);
var counter_2 = new Object();
counter_2.time = currentTime;
counter_2.reward_time = 600;
counter_2.finished = '#item_done_2';
counter_2.id = '#item_2';
AddCounter(counter_2);
var counter_3 = new Object();
counter_3.time = currentTime;
counter_3.reward_time = 1200;
counter_3.finished = '#item_done_3';
counter_3.id = '#item_3';
AddCounter(counter_3);
</script>
Now that the counters are created, several more functions are required. The first is the mystery AddCounter
function that is used several times above:
<script>
var counters = new Array();
function AddCounter(counter) {
counter_found = false;
for (var x = 0; x < counters.length; x++) {
if (counters[x].id == counter.id) {
counter_found = true;
break;
}
}
if (!counter_found) {
counters[counters.length] = counter;
}
}
</script>
The above code might be a bit of an overkill as I'm checking to make sure that the same counter is not created more than once in the array.
The final piece of code is creating a new interval that will fire every 1 second (1,000 milliseconds) and update all of the counters:
<script>
setInterval(UpdateCounters, 1000);
function UpdateCounters() {
currentTime++;
for (var x = 0; x < counters.length; x++) {
var counter = counters[x];
var time_left = counter.reward_time - (currentTime - counter.time);
var message = time_left + ' second';
if (time_left != 1) {
message += 's';
}
if (time_left < 0) {
$(counter.finished).show();
$(counter.id).remove();
} else {
$(counter.finished).hide();
$(counter.id).text(message);
}
}
}
</script>
In the final example, I loop through the counters array and perform a calculation to determine the number of seconds remaining and then update the message to display it.
Once the counter reaches 0
, the message is removed and a hidden element is shown indicating that the counter is done. This is great to display a link or form to allow the user to perform some sort of action.
Please note that Jquery is used for simplification of accessing the DOM.
Summary
Using a basic interval and looping through an array with a set of standard sub objects, JavaScript can easily manipulate the DOM to update any number of counters.
View the full source on my Git repo: https://github.com/endyourif/SampleCode/blob/master/javascript_timers.html
Photo courtesy of jovike