0

I have a countdown timer and when ever I rapidly press f5 the timer freezes. im guessing this is because the page reloads before the setInterval. i'm looking for a way to reload the page and at the same time keep the timer running whats happening is the page reloads before the setInterval could even finish

<h3 style="color:#000000" align="center">
         Time Remaining : <span id='timer'></span>
         </h3>

<script type="text/javascript" src="jquery-1.11.3.min.js"></script>
<script>

//define your time in second
    var c = localStorage.getItem("timer");
    if(c == null)c = 3600;

    var t;
    timedCount();

    function timedCount()
    {

        var hours = parseInt( c / 3600 ) % 24;
        var minutes = parseInt( c / 60 ) % 60;
        var seconds = c % 60;

        var result = (hours < 10 ? "0" + hours : hours) + ":" + (minutes <        10 ? "0" + minutes : minutes) + ":" + (seconds  < 10 ? "0" + seconds : seconds);


        $('#timer').html(result);
        if(c == 0 )
        {
            //setConfirmUnload(false);
            //$("#quiz_form").submit();
            window.location="logout.html";
        }
        c = c - 1;
        localStorage.setItem("timer", c);
        t = setTimeout(function()
        {
            timedCount()
        },1000);


    }


</script>
Arthur
  • 98
  • 2
  • 7
  • Do you need the timer to persist between page reload?, or what is it you actually want to achieve? – Asons Oct 13 '15 at 11:15

2 Answers2

5

Store the time that the timer should finish when the timer starts, then just subtract the current time from that value to get the time until the timer should finish. The Date object works well for this.

HTML

<p id="display">Time Left<p>
<button id="start">Start</button>

Javascript

var start = document.getElementById("start");
var dis = document.getElementById("display");
var finishTime;
var timerLength = 10;
var timeoutID;
dis.innerHTML = "Time Left: " + timerLength;

if(localStorage.getItem('myTime')){
    Update();
}
start.onclick = function () {
    localStorage.setItem('myTime', ((new Date()).getTime() + timerLength * 1000));
    if (timeoutID != undefined) window.clearTimeout(timeoutID);
    Update();
}

function Update() {
    finishTime = localStorage.getItem('myTime');
    var timeLeft = (finishTime - new Date());
    dis.innerHTML = "Time Left: " + Math.max(timeLeft/1000,0);
    timeoutID = window.setTimeout(Update, 100);
}

See working example here: JSFiddle

Paul Hansen
  • 1,167
  • 1
  • 10
  • 23
  • this is an excellent example of what i'm trying to achieve but the problem with this is that the user could change the time of the computer either forwards or backwards to extend or shorten the time – Arthur Oct 14 '15 at 02:01
  • Unfortunately anything calculated on the client side is always able to be circumvented. You can only make it harder for them. They could also set the local storage variable through the browser console so they don't even need to change the clock to cheat this. The most secure way would be to use server side code such as php or python. If you really need to keep this Javascript you could consider making your code as obscure as possible (hard for them to tell how to cheat it) and perhaps store the latest time every time you check and if the clock ever goes backwards you know they are cheating. – Paul Hansen Oct 14 '15 at 03:05
  • Can you explain why Math.max(timeLeft/1000,0); is returning as 0 maximum value ? Because timeLeft/1000 is 0.01 which greater than 0. I am so confused here. – Santosh Jan 01 '17 at 09:13
0

I am not sure what you are expecting to achieve by "rapidly pressing F5" but each time you press it you are reloading the page. This is reloading all of your javascript and restarting your timer. There is no way to keep a timer running through a page reload with client side code. Also, since javascript is single threaded, when the page reloads, your timer function is sent to the stack where it will wait to be executed as soon as the processor is ready for it. If you have functions called before the timer, they will be executed first. You can accomplish what you are trying to do by placing your timer on the server and getting its progress from the client when the page has loaded. Since I do not know what language your back end is written in, I can't provide you with an example of this.

buzzsaw
  • 1,476
  • 1
  • 10
  • 14
  • i'm not trying to achieve anything by rapidly pressing F5,i'm making a quiz application, and the timer is consistent through the pages but by reloading the page rapidly it freezes the timer. i was just wondering if there was a way around that, because the user could be able to cheat the time. – Arthur Oct 13 '15 at 11:42
  • No, there is no way around that on the client side. But, by placing the timer on your server they will not be able to do anything to impede its progress. It will only give the impression on the page that the timer is freezing when the page reloads but it will actually be running steady on your server. – buzzsaw Oct 13 '15 at 11:48
  • okay, so how am i going to able to to put the time inthe server? im using PHP – Arthur Oct 13 '15 at 12:18
  • There are many examples online about how to set up a server side timer in php. What you will need to figure out is how you want to track each one. It can be done using the user session token or any other unique identifier you wish to use. Then, when your page loads, you can also load the current timer progress, if it has been created and started. After the initial load, you can use javascript to increment it. If the user refreshes, it will go back to the server to get the current state of the timer. Javascript can then pick up where it left off. – buzzsaw Oct 13 '15 at 12:27
  • No problem. This sounds like a fun little project to work on! Enjoy the ride. – buzzsaw Oct 13 '15 at 12:33