Javascript script timer issue - javascript

I am trying to make a count down timer. I manage to make one but the problem with this is it stops when I close browser. So when user revisit my site it restart again. What I want is to keep that timer. For example, if user leaves my site at timer 22:14:09. So timer will continue. Lets say the user revisits my site after an hour so the time should be 21:14:09. How can I do that?
Here is my JS
$(function () {
var hrs, mins, secs, TimerRunning, TimerID,
Timer = {
init: function () {
hrs = 23;
mins = 59;
secs = 59;
TimerRunning = false;
Timer.StopTimer();
Timer.StartTimer();
},
StopTimer: function () {
if(TimerRunning)
clearTimeout(TimerID);
TimerRunning=false;
},
StartTimer: function () {
TimerRunning = true;
$('.timer').html(Timer.Pad(hrs) + ":" + Timer.Pad(mins) + ":" + Timer.Pad(secs));
TimerID = self.setInterval("StartTimer()", 1000);
if(hrs == 0 && mins == 0 && secs == 0)
StopTimer();
if (secs == 0) {
mins--;
secs = 59;
}
if (mins == 0) {
hrs--;
mins = 59;
}
secs--;
setTimeout(function () { Timer.StartTimer(); }, 1000);
},
Pad: function (number) {
if(number < 10)
number = 0+""+number;
return number;
}
};
Timer.init();
});
Update
DEMO

Here is my solution for this problem.
// use hours, minutes & seconds to set time limit
var hours = 1,
minutes = 30,
seconds = 0,
maxTime = ( ( hours * 3600 ) + ( minutes * 60 ) + seconds ) * 1000,
// if timeleft not in localStorage then default to maxTime
timeLeft = ( localStorage.timeLeft || maxTime ),
startTime = new Date(),
intervalRef;
// check if user has already used up time
if( timeLeft > 0 ) {
intervalRef = setInterval( setTimeLeft, 5000 );
} else {
stopTrackingTime();
}
function setTimeLeft( ) {
// if user has used up time exit
if( localStorage.timeLeft < 0 ) {
stopTrackingTime();
}
// calculate how long user has left
var elapsed = ( new Date() - startTime );
localStorage.timeLeft = timeLeft - elapsed;
};
// function called once user has used up time
function stopTrackingTime( ) {
clearInterval( intervalRef );
alert( "end of time allowed" );
}
Fiddle here

You could store the time in LocalStorage, and it would be persistent across browser restarts.
In your case something as simple as
localStorage["mytimer"] = JSON.stringify([hrs, mins, secs]);
should work for storage, and you could do
var previousTime = JSON.parse(localStorage["mytimer"]);
to retrieve the previous value.
You could read more about it here: http://diveintohtml5.info/storage.html.

You could modify your StartTimer function so that every time it is called a local time stamp (new Date) be saved in cookie or localStorage. Besides, the setTimeout isn't very reliable, your should adjust the time count with real time every now and then.

Related

Issue creating a countdown timer - minutes/seconds

I'm creating a countdown timer in minutes and seconds that that displays on the page - all seems to work fine with the bit of code I have. The only issue is when the alert box pops up I want the clock to stop counting down also.
I thought that including the return keyword under the alert pop up would resolve the issue but the clock keep ticking down.
Below is the code. Any help would be great.
window.onload = function() {
var hour = 1;
var sec = 59;
setInterval(function() {
document.getElementById("timer").innerHTML = hour + " : " + sec;
sec--;
if (sec == 0) {
hour--;
sec = 59;
}
if (hour == 1 && sec == 51)
{
alert("Stop, you have not completed the task in the alotted time");
return;
}
}, 1000);
}
To do that you need to save that Interval in a variable and then deactivate the interval with clearInterval. So your code would be like this:
window.onload = function() {
var hour = 1;
var sec = 59;
let counting_interval = setInterval(function() {
document.getElementById("timer").innerHTML = hour + " : " + sec;
sec--;
if (sec == 0) {
hour--;
sec = 59;
}
if (hour == 1 && sec == 51)
{
alert("Stop, you have not completed the task in the alotted time");
clearInterval(counting_interval); // pass the interval as the argument and it will stop to call the interval anymore
return;
}
}, 1000);
}
You need to set a timeout, not an interval. Intervals trigger until they're stopped. Timeouts happen once.
const interval = setInterval( function() {
document.getElementById("timer").innerHTML = hour + " : " + sec;
sec--;
if (sec == 0) {
hour--;
sec = 59;
}
});
const timeoutPeriod = 2 * 60 * 60 * 1000;
setTimeout(
function(){
clearInterval(interval);
alert("Stop, you have not completed the task in the alotted time");
}, timeoutPeriod
);

Javascript - Interval not clearing

I'm making a game that has a timer in it.
What I'm trying to do is -- when the game starts via gameState.init(), the timer starts through timer.counter("start") -- but when the "restart" button is clicked, the timer stops and resets through timer.counter("reset").
The timer does reset back to 0, but it keeps counting and not getting cleared.
Appreciate any insight I can get. Thanks in advance!
var gameState = {
init: function(){
var difficultyLevel = document.querySelector('input[name="level"]:checked').value;
conditions.difficulty(difficultyLevel);
startFrame.classList.remove("active");
shuffleCards();
timer.counter("start");
display.moves(movesAllowed);
},
restart: function(){
startFrame.classList.add("active");
reset.allCards(cards);
shuffleCards();
timer.counter("reset");
matchCount = 0;
totalMoves = 0;
movesAllowed = 0;
timeAllowed = 0;
time = 0;
}
}
var timer = {
counter: function(status){
var clock = document.querySelector(".timer");
var incrementTime = setInterval(function(){
time++;
var minutes = Math.floor(time / 60);
var seconds = Math.floor(time % 60);
if(seconds < 10){
clock.innerText = minutes + ":0" + seconds;
} else {
clock.innerText = minutes + ":" + seconds;
}
}, 1000);
var stopTime = function(){
clearInterval(incrementTime);
}
if(status === "start"){
alert("counting");
}
if(status === "reset"){;
alert("reset");
stopTime();
}
}
}
Two issues:
The variable that holds the interval, incrementTime, is local to the counter function. Once the counter function ends, incrementTime gets garbage collected, because no reference to the interval remains anymore. You need the interval variable to be persistent instead.
You're setting a new interval every time counter is called. You should probably only set an interval when status is start, otherwise the old interval will continue running and won't be stoppable (reassigning the interval a setInterval is assigned to doesn't clear the interval):
let interval; // <---- Persistent
var timer = {
counter: function(status){
var clock = document.querySelector(".timer");
if (status === 'start') {
interval = setInterval(() => { // <---- Assign to persistent variable
time++;
var minutes = Math.floor(time / 60);
var seconds = Math.floor(time % 60);
if(seconds < 10){
clock.innerText = minutes + ":0" + seconds;
} else {
clock.innerText = minutes + ":" + seconds;
}
}, 1000);
alert("counting");
} else if(status === "reset"){
var stopTime = function(){
clearInterval(interval); // <---- Clear persistent variable
}
alert("reset");
stopTime();
}
}
}
(It would also be a bit more elegant for the stopTime and interval functions to be persistent, rather than being re-created every time they're needed; eg, you might assign them to properties of timer)

Continuous Countdown Timer In Javascript or Jquery

I want to create a simple countdown timer in javascript or jquery.
I had implemented it using JS but what issue I am facing is if user refreshes the page then timer gets the refresh.
What I want is timer should not get the refresh.
Say timer is 5 min and if user refresh pages after 1 min the timer should continue to start from 4 min instead of 5 mins.
Here is code snippiet.
Its refresh the timer on page refresh.
var timeoutHandle;
function countdown(minutes) {
var seconds = 60;
var mins = minutes
function tick() {
var counter = document.getElementById("timer");
var current_minutes = mins-1
seconds--;
counter.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
if( seconds > 0 ) {
timeoutHandle=setTimeout(tick, 1000);
} else {
if(mins > 1){
// countdown(mins-1); never reach “00″ issue solved:Contributed by Victor Streithorst
setTimeout(function () { countdown(mins - 1); }, 1000);
}
}
}
tick();
}
countdown(2);
<div id="timer">2:00</div>
You just update the sessionStorage along with your counter and read it on starting the counter. Unfortunately the related snippet does not work on stackoverflow due to crossdomain policies - so here on codepen https://codepen.io/anon/pen/opNpVe
function countdown(seconds) {
seconds = parseInt(sessionStorage.getItem("seconds"))||seconds;
function tick() {
seconds--;
sessionStorage.setItem("seconds", seconds)
var counter = document.getElementById("timer");
var current_minutes = parseInt(seconds/60);
var current_seconds = seconds % 60;
counter.innerHTML = current_minutes + ":" + (current_seconds < 10 ? "0" : "") + current_seconds;
if( seconds > 0 ) {
setTimeout(tick, 1000);
}
}
tick();
}
countdown(120);

Continue Countdown Timer after visitor leaves website

My timer starts on window load. After a visitor closes my website page the timer pauses. If the visitor opens the same page (with timer) after 10 hours, the timer starts from the same time where it had paused earlier.
I want to create a 3 hour timer that starts when website page is loaded and that keeps ticking in the background even if the visitor is not currently visiting my website page.
I wish to redirect the visitor to another page say "amazon.com" after this 3 hour timer has expired, if he visits the website AFTER 3 hours.
function countdown() {
time = parseInt(localStorage.time);
if(isNaN(time) || time > (38 * 60)) {
//alert("An error occured: time left variable is corrupted, resetting timer");
localStorage.time = 38 * 60;
countdown();
return null;
}
if(time <= 0) {
alert("Your Timer Has Run Out! We Still Got 2 Discount Copies Left, Hurry Up!");
return null;
}
var timers = document.getElementsByClassName('timeleft');
Array.prototype.forEach.call(timers, function(timer) {
timer.innerText = formatTime(time);
})
time--;
localStorage.time = time;
setTimeout('countdown()', 1000);
}
function formatTime(time) {
minutes = Math.floor(time / 60);
seconds = time - minutes * 60;
if(String(seconds).length == 1) {
return String(minutes) + ":0" + String(seconds);
}
return String(minutes) + ":" + String(seconds);
}
window.onload = function() {
countdown();
}
<font size="+34"><div class="timeleft"></div></font>
I think you can just store the start time in localStorage, and compare it to the current time whenever the page is loaded:
function startOrRedirect () {
const startTime = localStorage.getItem('startTime')
if (startTime) {
const date1 = new Date(parseInt(startTime))
const date2 = new Date()
const hours = Math.abs(date1 - date2) / 36e5;
if (hours >= 3) {
redirect()
}
} else {
localStorage.setItem('startTime', Date.now)
setTimeout(redirect, 1000 * 60 * 60)
}
}
function redirect () {
window.location = 'https://amazon.com'
}
window.onload = startOrRedirect

Change JavaScript interval time when current time is between two times

I’m looking for a way to tweak a current script of mine that loads a page into a div every minute. I want it to wait 5 minutes at a specific time, then go back to executing every minute. Here’s what I have so far.
var starttime = 10‎:‎30:‎00‎ ‎PM;
var endtime = 10‎:‎35:‎00‎ ‎PM;
var myVar = setInterval(function(){ myTimer() }, 1000);
function myTimer() {
var d = new Date();
document.getElementById("currenttime").innerHTML = d.toLocaleTimeString();
if ( d.toLocaleTimeString() > ‎starttime &&
d.toLocaleTimeString() < ‎endtime ) {
setInterval(function() {
}, 300000);
$("#ticketload").load("loadlasttenminutesmodified.php");
} else {
setInterval(function() {
}, 60000);
$("#ticketload").load("loadlasttenminutesmodified.php");
}
};
Any help is appreciated, thanks.
var starttime = '10‎:‎30:‎00‎ ‎PM',
endtime = '10‎:‎35:‎00‎ ‎PM';
var myVar = setInterval(myTimer, 1000);
// Use this function instead of toLocaleTimeString,
// since inconsistencies may arise with that one, depending on country.
function getTimeFormatted(date) {
var hours = date.getHours(),
minutes = date.getMinutes(),
seconds = date.getSeconds(),
ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12;
minutes = minutes < 10 ? '0' + minutes : minutes;
seconds = seconds < 10 ? '0' + seconds : seconds;
return hours + ':' + minutes + ':' + seconds + ' ' + ampm;
}
function myTimer() {
var d = getTimeFormatted(new Date());
document.getElementById("currenttime").innerHTML = d;
// Simply return (exit) the function when current time is
// between both of those dates.
// Your function will not go further than this.
// And it will effectively do nothing other than update the innerHTML
// for about five minutes.
if (d > ‎starttime && d < ‎endtime) return;
// Do the stuff that is supposed to run every minute.
// I assume this is, but place whatever else you want in here.
$("#ticketload").load("loadlasttenminutesmodified.php");
}
You can just exit out of the interval with return when the time criteria is met, before executing the rest of the code that is supposed to run every minute.
I made some changes to your code:
You missed quotes in your starttime and endtime variables
Replaced toLocaleTimeString with a new function. Thanks to #SpiderPig for pointing out why toLocaleTimeString isn't reliable.
You can specify the function directly in the myVar interval, instead of executing the myTimer function inside of an anonymous function.
Format the current day into AM/PM once, since that's all that is needed.
return when the time criteria is met and before executing the rest of the code inside of the interval.
I don't know what those empty setIntervals were in there for, so I removed them. I guess this is just example code, judging from the variable names you gave.
Try
var startTime = "22:30:00",
endTime = "22:35:00",
currentTime = $("#currenttime"),
ticketLoad = $("#ticketload"),
delay = 60000,
extendedDelay = delay * 5,
timeout = null,
timer = function timer(delay) {
var cycle = function cycle(delay, reset) {
// clear `queue` if within `startTime` , `endTime` range,
// `reset` set to `true`
if (reset) {
this.queue("timer", []);
};
// `cycle` delay `60000`
this.html("currenttime called at:" + new Date().toLocaleString())
// set `cycle` delay to `300000`
// if within `startTime` , `endTime` range,
// `reset` set to `true`
var _delay = !reset ? delay : extendedDelay;
.delay(_delay, "timer")
.queue("timer", function() {
console.log(new Date().toLocaleString());
// continue cycle
timer.call($(this), _delay);
}).dequeue("timer");
// do ajax stuff
ticketLoad.load("loadlasttenminutesmodified.php")
.fail(function(jqxhr, textStatus, errorThrown) {
console.log(errorThrown);
// clear `queue` on `error`
currentTime.queue("timer", [])
});
};
// if within `startTime` , `endTime` range
// clear `queue` , set `cycle` delay to `300000`
if (String(new Date()).split(" ")[4] > startTime
&& String(new Date()).split(" ")[4] < endTime) {
cycle.call(this, delay, true);
timeout = setInterval(function() {
if (String(new Date()).split(" ")[4] >= endTime) {
clearInterval(timeout);
timeout = null;
this.queue("timer", []);
cycle.call(this, delay)
}
}.bind(this), 7500)
} else {
if (String(new Date()).split(" ")[4] >= endTime) {
this.queue("timer", []);
cycle.call($(this), delay)
} else {
cycle.call($(this), delay)
}
};
};
timer.call(currentTime, delay);
$(function() {
var startTime = "22:30:00",
endTime = "22:35:00",
currentTime = $("#currenttime"),
ticketLoad = $("#ticketload"),
delay = 60000,
extendedDelay = delay * 5,
timeout = null,
timer = function timer(delay, reset) {
var cycle = function cycle(delay, reset) {
if (reset) {
this.queue("timer", [])
};
var _delay = !reset ? delay : extendedDelay;
this.html("currenttime called at:" + new Date().toLocaleString())
.delay(_delay, "timer")
.queue("timer", function() {
console.log(new Date().toLocaleString());
timer.call($(this), _delay)
}).dequeue("timer");
$.when(ticketLoad)
.always(function(data) {
this.html("ticketLoad called at:" + new Date().toLocaleString())
})
};
if (String(new Date()).split(" ")[4] > startTime
&& String(new Date()).split(" ")[4] < endTime) {
cycle.call(this, delay, true);
timeout = setInterval(function() {
if (String(new Date()).split(" ")[4] >= endTime) {
clearInterval(timeout);
timeout = null;
this.queue("timer", []);
cycle.call(this, delay)
}
// check if beyond `endTime` ,
// reset `cycle`
// adjust interval duration here
// for greater, less frequency of checks
}.bind(this), 7500)
} else {
if (String(new Date()).split(" ")[4] >= endTime) {
this.queue("timer", []);
cycle.call($(this), delay)
} else {
cycle.call($(this), delay)
}
};
};
timer.call(currentTime, delay)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="currenttime"></div>
<div id="ticketload"></div>
Date.prototype.setMyTime = function (time) {
arrTime = time.split(":");
this.setHours(arrTime[0],arrTime[1],arrTime[2]);
return this;
}
var d = new Date();
var starttime = d.setMyTime('22:30:00');
var endtime = d.setMyTime('22:35:00');
var intervalId, loading = false;
var myVar = setInterval(function(){ myTimer() }, 1000);
function myTimer() {
var d = new Date();
document.getElementById("currenttime").innerHTML = d.toLocaleTimeString();
if(d.getTime() > starttime.getTime() && d.getTime() < endtime.getTime()) {
clearInterval(intervalId);
loading = false;
} else {
if (loading === false) {
intervalId = setInterval(function(){ $("#ticketload").load("loadlasttenminutesmodified.php"); }, 60000);
loading = true;
}
}
}
I decided to take a different approach. Set the interval to one minute and have and if statement inside that. Also, I needed to convert the time format into the same format as my variables.
<script type="text/javascript">
starttime = '10:30:00 PM';
endtime = '10:35:00 PM';
var myVar = setInterval(function(){ myTimer() }, 60000);
function myTimer() {
var timenow = new Date();
timeconvert = timenow.toLocaleTimeString()
if (timeconvert > starttime && timeconvert < endtime)
{
//alert("Time is 5 minutes");
}
else
{
//alert("Time is 60 seconds");
$("#ticketload").load("loadlasttenminutesmodified.php");
}
};
</script>
This has been working great all week.

Categories

Resources