Javascript visszaszámláló - Napi sorsoló

Ebben a cikkben bemutatom, hogyan lehet olyan idő visszaszámláló szkriptet írni, ami minden nap egy konkrét időpontig számol vissza, de ez az időpont lehet a másnap reggeli időpont is akár. Ehhez figyelembe kell venni a szerveridőt is, másképp a kliens ( talán hibás ) órájára lenne bízva, hogy mikor van vége a visszaszámlálásnak. Persze a visszaszámlálásnak akkor van értelme, ha a végén valami történik is. Így szerveroldalon PHP-ból gondoskodni kell arról is, hogy például lefusson egy sorsoló program, ami aztán az eredményeket megjeleníti. Ezt vagy Crontab időzítővel, ha a tárhelyen rendelkezésre áll, vagy eltárolva például adatbázisban, hogy aznap lefutott-e már a sorsolás, és ha még nem, de az idő már lejárt, akkor fusson le. És írja ki az eredményt. Persze a következő sorsolásig a visszaszámlálás már elindul. Ennek megvalósítását mindenkinek magára bízom. Én csak a számlálást mutatom be.

Először is kell két div ( vagy bármi más szöveges html elem ) amibe bekerül majd a visszaszámláló, és a lejáratkor megjelenítendő üzenet. Ezeknek id-ket kel adni. Legyenek "timediv" és "msgdiv" a két azonosító

  1. <div id="timediv"></div>
  2. <div id="msgdiv"></div>

Ez után szükség lesz egy php fájlra. Ebben elő kell állítani azt az időt, ameddig a visszaszámlálásnak tartania kell. És ezt a php változót kell átadni majd a javascript-nek.

  1. <?php
  2. $hour = 21; //Lejárat órája
  3. $min = 21; //lejárat perce
  4. $sec = 0;  //lejárat másodperce
  5.  
  6. $timeDivId = 'timediv'; //A html elem id-je, ahova a visszaszámláló kerül.
  7. $msgDivId = 'msgdiv'; //A html elem id-je, ahova a sorsolás üzenet kerül
  8. $msg = "Sorsolás folyamatban";
  9.  
  10. $time = time(); //jelenlegi szerveridő
  11. $time24 = mktime(24,0,0); //Aznap éjfél időpontja
  12.  
  13. $starttime = mktime($hour,$min,$sec); //a lejárat időpontja
  14. //Ha aznap már elmúlt a lejárati idő, akkor tegnaptól kell
  15. //kezdeni a visszaszámlálást
  16. if ($time < $starttime) {
  17.         $starttime-=86400;
  18. }
  19. //Javascriptben az időt nem mp-ben hanem ezred mp-ben kell megadni
  20. $jstime = ($time24  - $time + $starttime)*1000;
  21. header('Content-type: text/javascript');
  22. ?>

Itt tehát minden szükséges adatot meg lehet adni. De ezzel még nincs vége a fájlnak. Gyakorlatilag egy javascript fájl lesz php-ben. Ezért is adtam meg php headerben is a típust. Ezt ugyanúgy meg lehet majd hívni a következő módon, mint egy .js kiterjesztésű fájlt:

<script type="text/javascript" src="countDown24.js.php"></script>

De most akkor jöhet is a javascript része. Először egy névtelen függvényre lesz szükség. Nem lenne muszáj névtelen, de így legalább tutira nem lesz felülírva egy szükséges változó, vagy felüldefiniálva egy másik függvény a globális névtérben.

  1. (function (timeDivId, msgDivId,msg,jstime)
  2. {
  3.  
  4. })(<?php print '"'.$timeDivId.'","'.$msgDivId.'","'. $msg.'",'.$jstime ?>);

Na azért ebben is van php-, mint látszik. A függvény deklarációt zárójelbe tettem, és utána tettem egy () zárójelpárt, amiben php-val irattam ki a paramétereket. Ezzel a deklarációval le is fut a függvény, és nem kellett neki nevet adni. A paraméterek sorban a számlálót tartalmazó div id-je, a lejárat utáni üzenetet tartalmazó div id-je, az üzenet maga és a szerver idő alapján előállított javascript idő. Azaz idő ezredmásodpercekben számítva.

A változók, amire szükség lesz majd a függvényben.

  1.         var timediv = null;
  2.         var msgdiv = null;
  3.         var d = new Date(); //Dátum objektum létrehozása. Az időt később állítjuk be.
  4.         var i=0; //ciklusváltozó
  5.         var dots=''; //sorsolás folyamatjelző pontozás

Ezen kívül még 3 változó lesz, amik gyakorlatilag újabb függvények, de ebben a formában nem kerülnek be a globális térbe. Csak ebben a zárt, névtelen függvényben lesznek elérhetők, mint egy privát metódus.

Az első függvény az end() nevű. Ami akkor fut le, ha éppen lejárt az idő. Ez a lejárat után 1 perc intervallumot jelent majd. Nem mást tesz, mint kiírja a "Sorsolás folyamatban" szöveget a megfelelő div-be, és egy folyamatjelző animációt.

  1.         var end = function ()
  2.         {
  3.                 dots='';
  4.                 for(i=1; i<=4-(d.getSeconds() % 4);i++) {
  5.                         dots+='.';
  6.                 }
  7.                 msgdiv.innerHTML = msg + dots;
  8.         }

A következő maga a visszaszámlálás megvalósításának egy lépése. Ezt kell majd ismételni később:

  1.         var countDown = function()
  2.         {
  3.                 jstime-=1000;
  4.                 d.setTime(jstime);             
  5.                 var minute = (d.getMinutes() < 10) ? '0'+d.getMinutes() : d.getMinutes();
  6.                 var sec = (d.getSeconds() < 10) ? '0'+d.getSeconds() : d.getSeconds();
  7.                 timediv.innerHTML = d.getHours() + " : " + minute + " : " + sec;
  8.                 if(d.getHours() == '23' && d.getMinutes() == '59') {
  9.                         end();
  10.                 } else {
  11.                         msgdiv.innerHTML = "";
  12.                 }
  13.         }

Ez tehát 1 percig a lejárat idejekor megjeleníti a sorsolás szöveget, mert meghívja az end() függvényt. Más esetben pedig üresre állítja az üzenet div-et. Most jöhet tehát a start() függvény, ami ezt a lépést ismételgeti.

  1.         var start = function()
  2.         {
  3.                 timediv = document.getElementById(timeDivId);
  4.                 msgdiv = document.getElementById(msgDivId);
  5.                 //Ha bármelyik div nem létezik, nem fut le a program
  6.                 if (!timediv || !msgdiv)
  7.                 {
  8.                         return;
  9.                 }
  10.                 countDown();
  11.                 setInterval(countDown,1000);           
  12.         }

A setInterval() függvény fogja másodpercenként ismételgetni a countDown függvényt. És persze előtte lekérdezi a timediv és msdiv változókba a megfelelő div-eket ( vagy más html elemeket ). Mivel az ismételgető függvény előbb késleltet, aztán futtat, ezért előbb meg kell hívni külön a countDown() függvényt. Így a start meghívásakor azonnal látszik az eredmény. Ez persze így mind szép, de mégis hol lesz ez meghívva? Külön nincs szükség a meghívására, mert most megírjuk azt a pár sort, ami akár Firefox-ban, akár Internet Explorer-ben hozzáadja a window objektum onload eseményéhez a start függvényt. Nem pedig csak szimplán felülírja. Mert esetleg lehet, hogy már valami más script is hozzáadta magát az onload-hoz. És azt nem szeretnénk kilőni.

  1.         if (window.attachEvent) {
  2.                 window.attachEvent("onload",start);
  3.         } else {
  4.                 window.addEventListener("load",start,false);
  5.         }

Mivel a névtelen függvény azonnal lefut, így ez a fenti kódsor is egyből le fog futni. Viszont a start függvény csak akkor, amikor már a weboldal betöltött. És az pedig csak akkor indítja a visszaszámlálást, ha a szükséges div-ek léteznek. A teljes countDown24.js.php tartalma a következő:

  1. <?php
  2. $hour = 21; //Lejárat órája
  3. $min = 21; //lejárat perce
  4. $sec = 0;  //lejárat másodperce
  5.  
  6. $timeDivId = 'timediv'; //A html elem id-je, ahova a visszaszámláló kerül.
  7. $msgDivId = 'msgdiv'; //A html elem id-je, ahova a sorsolás üzenet kerül
  8. $msg = "Sorsolás folyamatban";
  9.  
  10. $time = time(); //jelenlegi szerveridő
  11. $time24 = mktime(24,0,0); //Aznap éjfél időpontja
  12.  
  13. $starttime = mktime($hour,$min,$sec); //a lejárat időpontja
  14. //Ha aznap már elmúlt a lejárati idő, akkor tegnaptól kell
  15. //kezdeni a visszaszámlálást
  16. if ($time < $starttime) {
  17.         $starttime-=86400;
  18. }
  19. //Javascriptben az időt nem mp-ben hanem ezred mp-ben kell megadni
  20. $jstime = ($time24  - $time + $starttime)*1000;
  21. header('Content-type: text/javascript');
  22. ?>
  1. (function (timeDivId, msgDivId,msg,jstime)
  2. {
  3.         var timediv = null;
  4.         var msgdiv = null;
  5.         var d = new Date();
  6.         var i=0;
  7.         var dots='';
  8.                
  9.         var end = function ()
  10.         {
  11.                 dots='';
  12.                 for(i=1; i<=4-(d.getSeconds() % 4);i++) {
  13.                         dots+='.';
  14.                 }
  15.                 msgdiv.innerHTML = msg + dots;
  16.         }
  17.  
  18.         var countDown = function()
  19.         {
  20.                 jstime-=1000;
  21.                 d.setTime(jstime);             
  22.                 var minute = (d.getMinutes() < 10) ? '0'+d.getMinutes() : d.getMinutes();
  23.                 var sec = (d.getSeconds() < 10) ? '0'+d.getSeconds() : d.getSeconds();
  24.                 timediv.innerHTML = d.getHours() + " : " + minute + " : " + sec;
  25.                 if(d.getHours() == '23' && d.getMinutes() == '59') {
  26.                         end();
  27.                 } else {
  28.                         msgdiv.innerHTML = "";
  29.                 }
  30.         }
  31.        
  32.         var start = function()
  33.         {
  34.                 timediv = document.getElementById(timeDivId);
  35.                 msgdiv = document.getElementById(msgDivId);
  36.                
  37.                 if (!timediv || !msgdiv)
  38.                 {
  39.                         return;
  40.                 }
  41.                 countDown();
  42.                 setInterval(countDown,1000);           
  43.         }
  44.        
  45.         if (window.attachEvent) {
  46.                 window.attachEvent("onload",start);
  47.         } else {
  48.                 window.addEventListener("load",start,false);
  49.         }
  50.        
  51. })(<?php print '"'.$timeDivId.'","'.$msgDivId.'","'. $msg.'",'.$jstime ?>)

A html pedig például:

  1.   <title>Visszaszámláló</title>
  2.         <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  3.         <script type="text/javascript" src="countDown24.js.php"></script>
  4. </head>
  5. <div id="timediv"></div>
  6. <div id="msgdiv"></div>
  7. </body>
  8. </html>

Demo: Megtekintés

Kategóriák: 
Megosztás/Mentés

Új hozzászólás