Reputation: 597
I found this in my search to create a JavaScript Countdown, but it doesn't seem to work for me. I'm surprised, as no one else seems to have reported having a problem. I must be missing something fundamental and I didn't know where else to turn, but here.
https://gist.github.com/nithinbekal/299417
Here is the code live on JSFiddle where it doesn't seem to function for me, either.
function updateWCTime() {
now = new Date();
kickoff = Date.parse("April 27, 2013 09:00:00");
diff = kickoff - now;
days = Math.floor( diff / (1000*60*60*24) );
hours = Math.floor( diff / (1000*60*60) );
mins = Math.floor( diff / (1000*60) );
secs = Math.floor( diff / 1000 );
dd = days;
hh = hours - days * 24;
mm = mins - hours * 60;
ss = secs - mins * 60;
document.getElementById("countdown")
.innerHTML =
dd + ' days ' +
hh + ' hours ' +
mm + ' minutes ' +
ss + ' seconds';
}
setInterval('updateWCTime()', 1000 );
Upvotes: 1
Views: 3273
Reputation: 66404
I'll propose an entirely different way of doing a countdown timer; a generator with a callback. At first you might wonder, why would I do it this way? But using a generator saves you a lot of code in re-used things. I've also used window.setTimeout
This is to ensure that you don't have nasty things happen if your callback takes longer to execute than your interval.
The comments through the code should help you understand what is happening.
// createCountDown(Date end_time [, Function callback, Integer ms_interval])
// returns an Object properties: ms, ss, mm, hh, dd, MM, yy, timer (current)
// same Object is passed as parameter 1 to callback
function createCountDown(time, callback, ms) {
var future = time.valueOf(), // cache these to save re-calling them later
f_ms = time.getUTCMilliseconds(),
f_ss = time.getUTCSeconds(),
f_mm = time.getUTCMinutes(),
f_hh = time.getUTCHours(),
f_dd = time.getUTCDate(),
f_MM = time.getUTCMonth(),
f_yy = time.getUTCFullYear(),
o = {timer: null}; // an object to make life easier
var f = function () { // the function that will handle the setTimeout loops
var d = new Date(), // the current time of each loop
remain = future - d.valueOf(); // difference (in ms)
if (remain > 0) {
// Totals
o['total_ms'] = remain; // if you'll never need all these, you can
o['total_ss'] = remain / 1000 | 0; // comment or cut them out
o['total_mm'] = remain / 60000 | 0;
o['total_hh'] = remain / 3600000 | 0;
o['total_dd'] = remain / 86400000 | 0;
// Differences (via UTC)
o['ms'] = (1000 + f_ms - d.getUTCMilliseconds()) % 1000; // same
o['ss'] = ( 60 + f_ss - d.getUTCSeconds() ) % 60;
o['mm'] = ( 60 + f_ss - d.getUTCMinutes() ) % 60;
o['hh'] = ( 24 + f_hh - d.getUTCHours() ) % 24;
o['dd'] = ( f_dd - d.getUTCDate() ) ; // below
o['MM'] = ( 12 + f_MM - d.getUTCMonth() ) % 12;
o['yy'] = ( f_yy - d.getUTCFullYear() ) ;
if (o['dd'] < 0) { // fix for negative days
d.setUTCMonth(d.getUTCMonth() + 1);
d.setUTCDate(0); // using number of days in current month
o['dd'] + d.getUTCDate();
}
callback(o); // invoke your callback
o.timer = window.setTimeout(f, ms); // set up next loop
}
}
ms || ms === 0 || (ms = 200); // default ms if not set
callback || (callback = function () {}); // default empty fn
f(); // start off the whole looping
return o;
}
Now write your callback
, this is much shorter, as you've got the long stuff out of the way. console.log
makes it easy for demonstrative purposes.
function updateWCTime(o) {
console.log(
o['total_dd'] + ' days ' +
o['hh'] + ' hours ' +
o['mm'] + ' minutes ' +
o['ss'] + ' seconds'
);
}
Finally, initiate it.
createCountDown(new Date("April 27, 2013 09:00:00"), updateWCTime);
Upvotes: 0
Reputation: 708136
You can fix your jsFiddle by either changing to:
setInterval(updateWCTime, 1000 );
or by changing the setting on the left panel of the jsFiddle from onload
to either of the no wrap
options. Here's a demonstration on only changing the jsFiddle left panel setting to "No wrap - in ": http://jsfiddle.net/jfriend00/rdj96/
Here's the explanation for why it didn't work. When you pass a string to setInterval()
like this:
setInterval('updateWCTime()', 1000 );
The javascript intepreter uses eval()
to evaluate the string and the function must be found in the global scope. But, because you have onload
in the left panel in the jsFiddle, all your javascript is inside another function (e.g. not global) so eval()
cannot find that function.
Changing your code to
setInterval(updateWCTime, 1000 );
allows javascript to just use a normal function reference and it can then find the function in your local scope (doesn't have to be global).
FYI, you should pretty much never pass a string to setInterval()
.
Upvotes: 1
Reputation: 49949
Change the interval to (live fiddle: http://jsfiddle.net/96TWk/1/)
setInterval(updateWCTime, 1000 );
The console says that the function updateWCTime
is not found, I don't know excactly why. Cu's it seems ok.
Upvotes: 2