Professional Documents
Culture Documents
Build A Countdown Timer in Just 18 Lines of JavaScript
Build A Countdown Timer in Just 18 Lines of JavaScript
Build A Countdown Timer in Just 18 Lines of JavaScript
YoucanreadmoreaboutdateformattinginJavaScriptinthisarticle.
CalculatetheTimeRemaining
ByYaphiBerhanuAugust28,2015
Sometimesinlife,youregoingtoneedaJavaScriptcountdownclockforsomethingotherthana
doomsdaydevice.Whetheryouhaveanevent,asale,apromotion,oragame,youcanbenefitfrom
buildingaclockinrawJavaScriptratherthanreachingforthenearestplugin.Whiletherearemanygreat
clockplugins,herearethebenefitsyoullgetfromusingrawJavaScript:
Yourcodewillbelightweightbecauseitwillhavezerodependencies.
Yourwebsitewillperformbetterbecauseyouwontneedtoloadexternalscriptsandstylesheets.
Youllhavemorecontrolbecauseyouwillhavebuilttheclocktobehaveexactlythewayyouwantitto
(ratherthantryingtobendaplugintoyourwill).
So,withoutfurtherado,hereshowtomakeyourowncountdownclockinamere18linesofJavaScript.
BasicClock:CountdowntoaSpecificDateorTime
Heresaquickoutlineofthestepsinvolvedincreatingabasicclock:
Setavalidenddate.
Calculatethetimeremaining.
Convertthetimetoausableformat.
Outputtheclockdataasareusableobject.
Displaytheclockonthepage,andstoptheclockwhenitreacheszero.
SetaValidEndDate
Thenextstepistocalculatethetimeremaining.Tomakethathappen,weneedtowriteafunctionthat
takesastringrepresentingagivenendtime(asoutlinedabove),andcalculatethedifferencebetween
thattimeandthecurrenttime.Hereswhatthatlookslike:
functiongetTimeRemaining(endtime){
vart=Date.parse(endtime)Date.parse(newDate());
varseconds=Math.floor((t/1000)%60);
varminutes=Math.floor((t/1000/60)%60);
varhours=Math.floor((t/(1000*60*60))%24);
vardays=Math.floor(t/(1000*60*60*24));
return{
'total':t,
'days':days,
'hours':hours,
'minutes':minutes,
'seconds':seconds
};
}
First,werecreatingavariablet,toholdtheremainingtimeuntilthedeadline.TheDate.parse()functionis
nativeJavaScriptthatconvertsatimestringintoavalueinmilliseconds.Thisallowsustosubtracttwo
timesfromeachotherandgettheamountoftimeinbetween.
vart=Date.parse(endtime) Date.parse(new Date());
ConverttheTimetoaUsableFormat
First,youllneedtosetavalidenddate.Thisshouldbeastringinanyoftheformatsunderstoodby
JavaScriptsDate.parse()method.Forexample:
TheISO8601format:
Nowwewanttoconvertthemillisecondstodays,hours,minutes,andseconds.Letsusesecondsasan
example:
varseconds= Math.floor( (t/1000) % 60 );
vardeadline='20151231';
Letsbreakdownwhatsgoingonhere.
Theshortformat:
vardeadline='31/12/2015';
1.
2.
Or,thelongformat:
3.
Dividemillisecondsby1000toconverttoseconds:(t/1000)
Dividethetotalsecondsby60andgrabtheremainderyoudontwantalloftheseconds,justtheones
remainingaftertheminuteshavebeencounted:(t/1000)%60
Roundthisdowntonearestwholenumberbecauseyouwantcompleteseconds,notfractionsof
seconds:Math.floor((t/1000)%60)
vardeadline='December312015';
Repeatthislogictoconvertthemillisecondstominutes,hours,anddays.
Eachoftheseformatsallowsyoutospecifyanexacttime(inhoursminutesandseconds),aswellasa
timezone(oranoffsetfromUTCinthecaseofISOdates).Forexample:
vardeadline='December31201523:59:59GMT+0200';
OutputtheClockDataasaReusableObject
Withthedays,hours,minutes,andsecondsprepared,werenowreadytoreturnthedataasareusable
object:
return{
'total':t,
'days':days,
'hours':hours,
'minutes':minutes,
'seconds':seconds
};
Calculatetheremainingtime.
Outputtheremainingtimetoourdiv.
Iftheremainingtimegetstozero,stoptheclock.
Atthispoint,theonlyremainingstepistoruntheclocklikeso:
initializeClock('clockdiv',deadline);
Congratulations!Younowhaveabasicclockinjust18linesofJavaScript.
PrepareYourClockforDisplay
Thisobjectallowsyoutocallyourfunctionandgetanyofthecalculatedvalues.Heresanexampleof
howyoudgettheremainingminutes:
Beforestylingtheclock,wellneedtorefinethingsalittle.
getTimeRemaining(deadline).minutes
Convenient,right?
Removetheinitialdelaysoyourclockshowsupimmediately.
Maketheclockscriptmoreefficientsoitdoesntcontinuouslyrebuildthewholeclock.
Addleadingzerosasdesired.
RemovetheInitialDelay
DisplaytheClockandStopItWhenItReachesZero
Nowthatwehaveafunctionthatspitsoutthedays,hours,minutes,andsecondsremaining,wecan
buildourclock.FirstwellcreatethefollowingHTMLelementtoholdourclock:
<divid="clockdiv"></div>
Thenwellwriteafunctionthatoutputstheclockdatainsideournewdiv:
functioninitializeClock(id,endtime){
varclock=document.getElementById(id);
vartimeinterval=setInterval(function(){
vart=getTimeRemaining(endtime);
clock.innerHTML='days:'+t.days+'<br>'+
'hours:'+t.hours+'<br>'+
'minutes:'+t.minutes+'<br>'+
'seconds:'+t.seconds;
if(t.total<=0){
clearInterval(timeinterval);
}
},1000);
}
Intheclock,weveusedsetIntervaltoupdatethedisplayeverysecond.Thisisfinemostofthetime,
exceptinthebeginningwhentherewillbeaoneseconddelay.Inordertoremovethisdelay,wellhave
toupdatetheclockoncebeforetheintervalstarts.
Todothis,letsmovetheanonymousfunctionthatwearepassingtosetInterval(theonethatupdatesthe
clockeverysecond)intoitsownseparatefunction,whichwecannameupdateClock.CalltheupdateClock
functiononceoutsideofsetInterval,andthencallitagaininsidesetInterval.Thisway,theclockshowsup
withoutthedelay.
InyourJavaScript,replacethis:
vartimeinterval= setInterval(function(){ ... },1000);
Withthis:
Thisfunctiontakestwoparameters:theidoftheelementthatwillcontainourclockandtheendtimeof
thecountdown.Insidethefunction,welldeclareavariablecalledclockanduseittostoreareferenceto
ourclockcontainerdivsothatwedonthavetokeepqueryingtheDOM.
Next,wellusesetIntervaltoexecuteananonymousfunctioneverysecond,whichwilldothefollowing:
functionupdateClock(){
vart=getTimeRemaining(endtime);
clock.innerHTML='days:'+t.days+'<br>'+
'hours:'+t.hours+'<br>'+
'minutes:'+t.minutes+'<br>'+
'seconds:'+t.seconds;
if(t.total<=0){
clearInterval(timeinterval);
}
}
updateClock();//runfunctiononceatfirsttoavoiddelay
vartimeinterval=setInterval(updateClock,1000);
AvoidContinuouslyRebuildingtheClock
Tomaketheclockscriptmoreefficient,wellwanttoupdateonlythenumbersintheclockinsteadof
rebuildingtheentireclockeverysecond.Onewaytoaccomplishthisistoputeachnumberinsideaspan
tagandonlyupdatethecontentofthosespans.
Ifyoudlike,youcanaddleadingzerostotheminutesandhoursaswell.Ifyouvecomethisfar,
congratulations!Yourclockisnowreadyfordisplay.
Note:YoumayhavetoclickRerunintheCodePenforthecountdowntostart.
TakingitFurther
HerestheHTML:
Thefollowingexamplesdemonstratehowtoexpandtheclockforcertainusecases.Theyareallbased
onthebasicexampleseenabove.
<divid="clockdiv">
Days:<spanclass="days"></span><br>
Hours:<spanclass="hours"></span><br>
Minutes:<spanclass="minutes"></span><br>
Seconds:<spanclass="seconds"></span>
</div>
ScheduletheClockAutomatically
Nowletsgetareferencetothoseelements.Addthefollowingcoderightafterwheretheclockvariable
isdefined
Letssaywewanttheclocktoshowuponcertaindaysbutnotothers.Forexample,wemighthavea
seriesofeventscomingupanddontwanttomanuallyupdatetheclockeachtime.Hereshowto
schedulethingsinadvance.
HidetheclockbysettingitsdisplaypropertytononeintheCSS.ThenaddthefollowingtotheinitializeClock
function(afterthelinethatbeginswithvarclock).Thiswillcausetheclocktoonlydisplayoncethe
initializeClockfunctioniscalled:
vardaysSpan=clock.querySelector('.days');
varhoursSpan=clock.querySelector('.hours');
varminutesSpan=clock.querySelector('.minutes');
varsecondsSpan=clock.querySelector('.seconds');
clock.style.display= 'block';
Next,weneedtoaltertheupdateClockfunctiontoupdateonlythenumbersinsteadofrebuildingthe
wholeclock.Thenewcodewilllooklikethis:
functionupdateClock(){
vart=getTimeRemaining(endtime);
daysSpan.innerHTML=t.days;
hoursSpan.innerHTML=t.hours;
minutesSpan.innerHTML=t.minutes;
secondsSpan.innerHTML=t.seconds;
...
}
Nextwecanspecifythedatesbetweenwhichtheclockshouldshowup.Thiswillreplacethedeadline
variable:
varschedule=[
['Jul252015','Sept202015'],
['Sept212015','Jul252016'],
['Jul252016','Jul252030']
];
Eachelementintheschedulearrayrepresentsastartdateandanenddate.Asnotedabove,itispossible
toincludetimesandtimezones,butIusedplaindatesheretokeepthecodereadable.
AddLeadingZeros
Nowthattheclockisupdatingthenumbersinsteadofrebuildingeverysecond,wehaveonemorething
todo:addleadingzeros.Forexample,insteadofhavingtheclockshow7seconds,itwouldshow07
seconds.Onesimplewaytodothisistoaddastringof0tothebeginningofanumberandthenslice
offthelasttwodigits.
Forexample,toaddaleadingzerotothesecondsvalue,youdchangethis:
secondsSpan.innerHTML=t.seconds;
tothis:
secondsSpan.innerHTML=('0' + t.seconds).slice(2);
Finally,whenauserloadsthepage,weneedtocheckifwearewithinanyofthespecifiedtimeframes.
ThiscodeshouldreplacethepreviouscalltotheinitializeClockfunction.
//iterateovereachelementintheschedule
for(vari=0;i<schedule.length;i++){
varstartDate=schedule[i][0];
varendDate=schedule[i][1];
//putdatesinmillisecondsforeasycomparisons
varstartMs=Date.parse(startDate);
varendMs=Date.parse(endDate);
varcurrentMs=Date.parse(newDate());
//ifcurrentdateisbetweenstartandenddates,displayclock
if(endMs>currentMs&¤tMs>=startMs){
initializeClock('clockdiv', endDate);
}
}
Nowyoucanscheduleyourclockinadvancewithouthavingtoupdateitbyhand.Youmayshortenthe
codeifyouwish.Imademineverboseforthesakeofreadability.
CountdownfromWhentheUserArrives
Sometimesitsnecessarytosetacountdownforagivenamountoftimefromwhentheuserarrivesor
startsaspecifictask.Wellusetenminuteshere,butyoucanuseanyamountoftimeyouwant.
Allweneedtodohereisreplacethedeadlinevariablewiththis:
vartimeInMinutes=10;
varcurrentTime=Date.parse(newDate());
vardeadline=newDate(currentTime+ timeInMinutes*60*1000);
Thiscodetakesthecurrenttimeandaddstenminutes.Thevaluesareconvertedintomilliseconds,so
theycanbeaddedtogetherandturnedintoanewdeadline.
Nowwehaveaclockthatcountsdowntenminutesfromwhentheuserarrives.Feelfreetoplayaround
andtrydifferentlengthsoftime.
else{
//createdeadline10minutesfromnow
vartimeInMinutes=10;
varcurrentTime=Date.parse(newDate());
vardeadline=newDate(currentTime+timeInMinutes*60*1000);
//storedeadlineincookieforfuturereference
document.cookie='myClock='+deadline+';path=/;domain=.yourdomain.com';
}
Thiscodemakesuseofcookiesandregularexpressions,bothofwhichareseparatetopicsintheirown
right.Forthatreason,Iwontgointotoomuchdetailhere.Theoneimportantthingtonoteisthatyoull
needtochange.yourdomain.comtoyouractualdomain.Ifyouhaveanyquestionsconcerningthis,letme
knowinthecomments.
AnImportantCaveataboutClientSideTime
JavaScriptdatesandtimesaretakenfromtheuserscomputer.Thatmeanstheusercanaffecta
JavaScriptclockbychangingthetimeontheirmachine.Inmostcases,thiswontmatter,butinthecase
ofsomethingsupersensitive,itwillbenecessarytogetthetimefromtheserver.Thatcanbedonewith
abitofPHPorAjax,bothofwhicharebeyondthescopeofthistutorial.
Inanycase,aftergettingthetimefromtheserver,wecanworkwithitusingthesameclientside
techniquesfromthistutorial.
Conclusion
MaintainClockProgressacrossPages
Sometimesitsnecessarytopreservethestateoftheclockformorethanjustthecurrentpage.For
example,ifwewantedatenminutecountdownacrossthesite,wewouldntwanttheclocktoreset
everytimetheusergoestoadifferentpageoreverytimetheuserrefreshesthepagetheyareon.
Onesolutionistosavetheclocksendtimeinacookie.Thatway,navigatingtoanewpagewontreset
theendtimetotenminutesfromnow.
Wevecoveredhowtomakeabasiccountdownclockandprepareitforefficientdisplay.Wevealso
goneoverscheduling,absoluteversusrelativetimesandpreservingtheclocksstateacrosspageviews.
WhatsNext?
Playaroundwithyourclockcode.Tryaddingsomecreativestyles,ornewfeatures(suchaspauseand
resumebuttons).Ifyoucomeupwithanycoolclockexamplesyoudliketoshare,orhaveanyquestions
aboutwhatwevecoveredhere,pleaseletmeknowinthecomments.
Heresthelogic:
1.
2.
Ifadeadlinewasrecordedinacookie,usethatdeadline.
Ifthecookieisntpresent,setanewdeadlineandstoreitinacookie.
Toimplementthis,replacethedeadlinevariablewiththefollowing:
//ifthere'sacookiewiththenamemyClock,usethatvalueasthedeadline
if(document.cookie&&document.cookie.match('myClock')){
//getdeadlinevaluefromcookie
vardeadline=document.cookie.match(/(^|;)myClock=([^;]+)/)[2];
}
//otherwise,setadeadline10minutesfromnowand
//saveitinacookiewiththatname