Vous êtes sur la page 1sur 4

BuildaCountdownTimerinJust18LinesofJavaScript

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&&currentMs>=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

Vous aimerez peut-être aussi