I have a problem what happens is that I am taking a type of exam, so that exam has its questions and everything is perfect, the exam has a timer, the problem is that when the page is reloaded the timer starts again, does anyone know what I can do so that the timer does not restart when the page is reloaded, that is, if the user reloads the page, the timer starts from where it left off before the user reloaded the page.
// Temporizador
function startTimer(time) {
counterTime = setInterval(timerCount, 1000);
function timerCount() {
if (time <= 600) {
let iconItem = document.querySelector(".btn-shop + p");
iconItem.style.color = "#F7931E";
iconItem.style.fontSize = "2.4rem";
let icon = document.querySelector(".fa-clock");
icon.classList.add("shake-bottom");
icon.style = "animation-iteration-count: infinite;";
}
if (time <= 300) {
let iconItem = document.querySelector(".btn-shop + p");
iconItem.style.color = "#d52039";
iconItem.style.fontSize = "2.4rem";
let icon = document.querySelector(".fa-clock");
icon.classList.add("shake-bottom");
icon.style = "animation-iteration-count: infinite;";
// let message = document.getElementById(".message");
// message.classList.replace("d-none", "d-block")
}
if (time == 0) {
// let button = document.querySelector("#nextQuestion");
// button.innerHTML = "Entregar Examen";
// button.href = "./dashb-final-examen.html";
window.location.replace("./dashb-final-examen.html");
clearInterval(counterTime);
}
String.prototype.toHHMMSS = function () {
let sec_num = parseInt(this, 10);
let hours = Math.floor(sec_num / 3600);
let minutes = Math.floor((sec_num - hours * 3600) / 60);
let seconds = sec_num - hours * 3600 - minutes * 60;
if (hours < 10) {
hours = "0" + hours;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 10) {
seconds = "0" + seconds;
}
// console.log(hours + ':' + minutes + ':' + seconds)
return hours + ":" + minutes + ":" + seconds;
};
let realTime = time.toString();
timer.textContent = realTime.toHHMMSS();
time--;
}
}
startTimer(305);
window.addEventListener("beforeunload", function(e) {
// funciona, lo mismo que si devolviera desde window.onbeforeunload
// if time is not over
if (time > 0) {
// save the time
document.cookie = "time=" + time;
} else {
// delete the cookie if time is over
document.cookie = "time=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
}
});
window.addEventListener("onload", function(){
var cookie = document.cookie;
// if cookie is not empty
if (cookie != "") {
// get the time from the cookie
var cookieTime = cookie.split("=")[1];
// if time is not over
if (cookieTime > 0) {
// set the time
time = cookieTime;
}
}
})
Try this
window.addEventListener("beforeunload", function(e) {
// if time is not over
if (time > 0) {
// save the time
document.cookie = "time=" + time;
} else {
// delete the cookie if time is over
document.cookie = "time=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
}
};
window.onload = function() {
// get the cookie
var cookie = document.cookie;
// if cookie is not empty
if (cookie != "") {
// get the time from the cookie
var cookieTime = cookie.split("=")[1];
// if time is not over
if (cookieTime > 0) {
// set the time
time = cookieTime;
}
}
};
Related
I'm learning JS and I'm stuck...
I want to create a countdown (it's done, my countdown is working) who keep running when the page is reloaded.
I used the sessionStorage to "save" the countdown value and also to check if a sessionStorage exists when the page is loaded.
The problem is, I don't know how keep running the countdown with values saved in the sessionStorage.
Could you please help me?
class Timer {
constructor(secondes, minutes) {
this.secondes = secondes;
this.minutes = minutes;
this.button = document.getElementById("button");
this.counter = document.getElementById("counter");
this.storageCheck();
}
countdown(minutes) {
var seconds = this.secondes;
var mins = this.minutes;
var myCounter = this.counter;
function tick() {
var current_minutes = mins-1;
seconds--;
myCounter.innerHTML = current_minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
var duration = sessionStorage.setItem("timer", myCounter.innerHTML);
if( seconds > 0 ) {
setTimeout(tick, 1000);
} else {
if(mins > 1){
countdown(mins-1);
}
}
}
tick();
}
buttonClick() {
button.addEventListener("click", () => {
this.countdown(this.minutes);
})
}
storageCheck() {
if (sessionStorage.getItem("timer")) {
// keep the countdown running
}
}
}
let newTimer = new Timer(60, 20);
newTimer.buttonClick();
<!DOCTYPE html>
<html>
<head>
<title>Test Countdown</title>
</head>
<body>
<div id="counter"></div>
<button id="button">Run</button>
<script type="text/javascript" src="countdown.js"></script>
</body>
</html>
In constructor before initializing secondes and minutes check if they are in the storage.If they dont exists then only set the this.secondes = secondes and this.minutes = minutes;
constructor(secondes, minutes) {
this.button = document.getElementById("button");
this.counter = document.getElementById("counter");
if(!this.storageCheck()){ //check if seconds are mins are stored in storage
this.secondes = secondes; //if not set mins and sec to value passed in constructor
this.minutes = minutes;
}
else{
this.countdown(this.minutes);
}
}
In storage check function , check if the values are there, if there get the values and set to this.secondes and this.minutes and return true else return false
storageCheck() {
//if both mins and secs exists
if (sessionStorage.getItem("mins") &&sessionStorage.getItem("secs")) {
// keep the countdown running
this.minutes=parseInt(sessionStorage.getItem("mins"));//get min
this.secondes=parseInt(sessionStorage.getItem("secs"));//get secs
return true;
}
else
return false;
}
and in countdown funciton save the values to storage
sessionStorage.setItem("mins",vm.minutes);//set current min
sessionStorage.setItem("secs",vm.secondes);//set current sec
Try running this here :https://jsbin.com/bavexigute/1/edit?html,js,console,output
class Timer {
constructor(secondes, minutes) {
this.button = document.getElementById("button");
this.counter = document.getElementById("counter");
if(!this.storageCheck()){ //check if seconds are mins are stored in storage
this.secondes = secondes; //if not set mins and sec to value passed in constructor
this.minutes = minutes;
}
else{
this.countdown();
}
}
countdown() {
debugger;
var vm=this;
if(!(this.minutes-1<0))
this.minutes--;
let tick= function(){
vm.secondes--
if(vm.secondes==0){
vm.secondes=59;
vm.minutes--;
}
vm.counter.innerHTML = vm.minutes + ":" + (vm.secondes < 10 ? "0" : "") + vm.secondes;
if(vm.minutes == 0 && vm.secondes-1==0){
vm.secondes--;
vm.counter.innerHTML = vm.minutes + ":" + vm.secondes-1;
}
else{
setTimeout(tick,1000);
}
sessionStorage.setItem("mins",vm.minutes);//set current min
sessionStorage.setItem("secs", vm.secondes);//set current sec
}
setTimeout(tick,1000);
}
buttonClick() {
button.addEventListener("click", () => {
this.countdown();
})
}
storageCheck() {
//if both mins and secs exists
if (sessionStorage.getItem("mins") && sessionStorage.getItem("secs")) {
// keep the countdown running
this.minutes=parseInt(sessionStorage.getItem("mins"));//get min
this.secondes=parseInt(sessionStorage.getItem("secs"));//get secs
return true;
}
else
return false;
}
}
let newTimer = new Timer(60, 20);
newTimer.buttonClick();
You could use your storage check function to override the minutes and seconds arguments if it exists.
constructor(mins, secs) {
this.mins = mins
this.secs = secs
this.checkStorage = this.checkStorage.bind(this)
this.checkStorage(mins, secs)
}
checkStorage(mins, secs) {
if(window.storage) { // or whatever
this.secs = window.storage.secs
this.mins = window.storage.mins
}
}
Something along those lines. Basically just have the setStorage function change the values that have been set in the constructor.
You can do a simple trick by doing this
window.onload = function() {
let minutes = sessionStorage.getItem("minutes")
let seconds = sessionStorage.getItem("seconds")
let newTimer = new Timer(seconds, minutes);
};
And in sessionStorage instead of storing the whole innerHtml store minutes and seconds hopefully it will solve your problem
I am building an aptitude test with a timer. i want to show a div of time out on countdown finish. and is it possible to show a **Lean Modal Popup ** box on countdown finish. Please help!!!. Heres the code
Javascript
<script language="JavaScript" type="text/javascript">
function CountDownTimer(duration, granularity) {
this.duration = duration;
this.granularity = granularity || 1000;
this.tickFtns = [];
this.running = false;
}
CountDownTimer.prototype.start = function() {
if (this.running) {
return;
}
this.running = true;
var start = Date.now(),
that = this,
diff, obj;
(function timer() {
diff = that.duration - (((Date.now() - start) / 1000) | 0);
if (diff > 0) {
setTimeout(timer, that.granularity);
} else {
diff = 0;
that.running = false;
}
obj = CountDownTimer.parse(diff);
that.tickFtns.forEach(function(ftn) {
ftn.call(this, obj.minutes, obj.seconds);
}, that);
}());
};
CountDownTimer.prototype.onTick = function(ftn) {
if (typeof ftn === 'function') {
this.tickFtns.push(ftn);
}
return this;
};
CountDownTimer.prototype.expired = function() {
return !this.running;
};
CountDownTimer.parse = function(seconds) {
return {
'minutes': (seconds / 60) | 0,
'seconds': (seconds % 60) | 0
};
};
window.onload = function () {
var display = document.querySelector('#time'),
timer = new CountDownTimer(5),
timeObj = CountDownTimer.parse(5);
format(timeObj.minutes, timeObj.seconds);
timer.onTick(format);
document.querySelector('button').addEventListener('click', function () {
timer.start();
});
function format(minutes, seconds) {
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ':' + seconds;
}
if(display.textContent == 0){
document.querySelector("#div1").style.display="block";
}
};
</script>
Html
<button>Start Count Down</button>
<div>Registration closes in <span id="time"></span> minutes!</div>
div to show
<div id="div1" style="display:none;" ><p>Hello</p></div>
Ok, so the thing is, you have this piece of javascript code:
window.onload = function () {
var display = document.querySelector('#time'),
timer = new CountDownTimer(5),
timeObj = CountDownTimer.parse(5);
format(timeObj.minutes, timeObj.seconds);
timer.onTick(format);
document.querySelector('button').addEventListener('click', function () {
timer.start();
});
function format(minutes, seconds) {
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ':' + seconds;
}
if(display.textContent == 0){
document.querySelector("#div1").style.display="block";
}
At the bottom, you have an "if" statement.
Just move that if statement into the "format" function as follow:
window.onload = function () {
var display = document.querySelector('#time'),
timer = new CountDownTimer(5),
timeObj = CountDownTimer.parse(5);
format(timeObj.minutes, timeObj.seconds);
timer.onTick(format);
document.querySelector('button').addEventListener('click', function () {
timer.start();
});
function format(minutes, seconds) {
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ':' + seconds;
console.log(display.textContent);
if(display.textContent == "00:00") {
document.querySelector("#div1").style.display="block";
}
}
};
Your code, the way it currently is, is not performing the check on every tick.
Also, you are not checking against "0". The value should be "00:00"
Of course, you can move the check to show the div into the tick event, but that is totally up to you.
here is my code in which i have use readCookies function but when it's not responding, it shows nothing in the div even alert is also not working.
seconds = readCookie('countdown') || 60;
alert(seconds);
function secondPassed() {
seconds--;
var minutes = parseInt(seconds / 60);
var remainingSeconds = parseInt(seconds % 60);
if (remainingSeconds < 10) {
remainingSeconds = "0" + parseInt(remainingSeconds);
}
document.getElementById('countdown').innerHTML = minutes + " mins : " + remainingSeconds + " secs";
if (parseInt(seconds) === 0) {
alert("Time is over");
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "Time is Over";
document.forms["myForm"].submit();
document.location.href = "examresult.jsp";
}
}
var countdownTimer = setInterval(function () {
secondPassed();
if (seconds === 0) {
eraseCookie(seconds);
} else {
createCookie(seconds, seconds, 7);
}
}, 1000);
Store the value in a cookie or browser storage, before page unload and re-load it from cookie or browser storage in page refresh.
For example (pseudo-code):
window.onunload = function(){
set_cookie('timer', timer) /* you need to implement this function */;
}
window.onload = function() {
timer = get_cookie('timer'); /* you need to implement this function */
if ( null == timer ) timer = 0; /* not page refresh, start a new timer */
}
I am new in javascript, I want to create a countdown timer with localStorage which starts from given time and end to 00:00:00, but it's not working,
When I am running my code it is showing value "1506".
Here is my code
<script type="text/javascript">
if (localStorage.getItem("counter")) {
var CurrentTime = localStorage.getItem("counter");
}
else {
var Hour = 3;
var Minute = 25;
var Second = 60;
var CurrentTime = Hour.toString() + ":" + Minute.toString() + ":" + Second.toString();
}
function CountDown() {
document.getElementById('lblDuration').innerHTML = CurrentTime;
Second--;
if (Second == -1) {
Second = 59;
Minute--;
}
if (Minute == -1) {
Minute = 59;
Hour--;
}
localStorage.setItem("counter", CurrentTime);
}
var interval = setInterval(function () { CountDown(); }, 1000);
</script>
you need to declare variables Hour, Minute, Second, CurrentTime out side if else block. In this case they are not in function CountDown() scope.
you are not setting CurrentTime = Hour.toString() + ":" + Minute.toString() + ":" + Second.toString(); after localStorage.setItem("counter", CurrentTime);
var Hour = 3;
var Minute = 25;
var Second = 60;
var CurrentTime = Hour.toString() + ":" + Minute.toString() + ":" + Second.toString();
function CountDown() {
document.getElementById('lblDuration').innerHTML = CurrentTime;
Second--;
if (Second == -1) {
Second = 59;
Minute--;
}
if (Minute == -1) {
Minute = 59;
Hour--;
}
CurrentTime = Hour.toString() + ":" + Minute.toString() + ":" + Second.toString();
}
setInterval(function () {
CountDown();
}, 1000);
<div id="lblDuration"></div>
When localStorage is available you don set the values for Hour, Minute and Second. So when the countdown function executed it finds Second to be undefined and the statement Second-- converts Second to NaN.
To fix it just initialize the Hour, Minute and Second Variable.
I 've refactored your code a little bit hope it helps:
function CountDown() {
var currentTime = getCurrentTime();
printCurrentTime(currentTime)
currentTime.second--;
if (currentTime.second == -1) {
currentTime.second = 59;
currentTime.minute--;
}
if (currentTime.minute == -1) {
currentTime.minute = 59;
currentTime.hour--;
}
setCurrentTime(currentTime);
}
function setCurrentTime(newCurrentTime){
if(localStorage) localStorage.setItem("counter", JSON.stringify(newCurrentTime));
else setCurrentTime.storage = newCurrentTime;
}
function getCurrentTime(){
var result = localStorage ? localStorage.getItem("counter") : setCurrentTime.storage;
result = result || {hour:3, minute:25, second:60};
if (typeof(result) === "string")result = JSON.parse(result);
result.toString = function(){
return result.hour + ":" + result.minute + ":" + result.second;
}
return result;
}
function printCurrentTime(currentime){
var domTag = document.getElementById('lblDuration');
if(domTag) domTag.innerHTML = currentime.toString();
else console.log(currentime);
}
setInterval(function () { CountDown(); }, 1000);
Il try to explain this as simple as I can.
I'm trying to make a timer app for practice. User should be abble to add a new Object, wich will be a timer + stop/start buttons.
At this point, its working with one object, but when I create another object, the old one stops working(i belive it loses the pointer to it, or somthing like that), and the new one works.
Dont worry, about the buttons functionality,thats not important, all I want to understand how do I save the object, after a new one is created.
here is JS:
var startTime = 0;
var itemNum = 0;
var obName;
var arrayForTimers = [];
function timerObject(obName) {
this.nameField = "start";
this.classField = "timer";
this.block = " ";
this.obName = obName;
this.startButton = " ";
this.stopButton = " ";
this.placeholder = document.getElementsByClassName("timer-placeholder")[0];
this.addBlock = function () {
this.block = document.createElement("DIV");
this.block.className = this.classField;
this.block.className += " " + this.obName;
this.placeholder.appendChild(this.block);
}
this.renderTime = function () {
this.startTime = startTime;
this.endTime = new Date();
// time difference in ms
this.timeDiff = this.endTime - this.startTime;
// strip the miliseconds
this.timeDiff /= 1000;
// get seconds
this.seconds = Math.round(this.timeDiff % 60);
// remove seconds from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get minutes
this.minutes = Math.round(this.timeDiff % 60);
// remove minutes from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get hours
this.hours = Math.round(this.timeDiff % 24);
this.block.innerHTML = this.hours + " h " + this.minutes + " min " + this.seconds + " sec";
// window.setInterval('this.obName.renderTime()',1000);// Uncomment if you want to test your PCs limit
}
this.renderButtons = function () {
var timePassed;
//this.parentTimer = document.getElementsByClassName("timer "+this.obName)[0];
this.startButton = document.createElement("INPUT");
this.startButton.setAttribute("type", "button");
this.startButton.setAttribute("value", "start");
this.startButton.className = "start " + this.obName;
this.stopButton = document.createElement("INPUT");
this.stopButton.setAttribute("type", "button");
this.stopButton.setAttribute("value", "stop");
this.stopButton.className = "stop " + this.obName;
this.placeholder.insertBefore(this.startButton, this.block);
this.placeholder.insertBefore(this.stopButton, this.block);
this.startButton.addEventListener("click", function () {
//if (this.hours === 0 && this.minutes === 0 && this.seconds === 0){
this.startTime = new Date();
// }
tm = window.setInterval('obName.renderTime()', 1000);
})
this.stopButton.addEventListener("click", function () {
window.clearInterval(tm);
//timePassed = this.endTime - this.startTime;
//endTime = new Date();
// timePassed = endTime - startTime;
})
//give listener to clear and start interval
}
};
function createNewTimer() {
obName = document.getElementById("ObName").value;
if (obName !== "") {
obName = new timerObject(obName);
obName.addBlock();
obName.renderButtons();
startTime = new Date();
obName.renderTime();
//arrayForTimers.push(obName);
//window.setInterval('obName.renderTime()',1000);
} else {
document.getElementById("ObName").value = "Fill me";
}
};
Here is a Js Fiddle http://jsfiddle.net/3qxoea52/4/
P.S. sorry for my grammar, not my native languege.
Thanks.
The problem is here
tm = window.setInterval('obName.renderTime()', 1000);
This means that when you click any of the start buttons it will always start the object currently associated with obName.
Also, you only have a single global variable tm to store the timer, so when you do
window.clearInterval(tm);
It is clearing whichever timer was last set.
And you also have a single global startTime, which is causing all of the timers to reset whenever you create a new timer.
Another problem is that you have nothing to store the time when you stop each timer, so if you stop then restart it, it will not continue at the same point.
You can fix these problems by:
using self = this to create a stable reference to the object
use function.bind to make sure an event handler will be bound to the right timer object
add a property this.startDiff so that the time is saved when you stop then restart the clock
make tm a local variable within the TimerObject
set this.startTime within the object instead of outside it.
-- as in the code below (jsfiddle)
function TimerObject(obName) {
var self = this,
tm;
this.startTime = new Date();
this.startDiff = 0;
this.nameField = "start";
this.classField = "timer";
this.block = " ";
this.obName = obName;
this.startButton = " ";
this.stopButton = " ";
this.placeholder = document.getElementsByClassName("timer-placeholder")[0];
this.addBlock = function () {
this.block = document.createElement("DIV");
this.block.className = this.classField;
this.block.className += " " + this.obName;
this.placeholder.appendChild(this.block);
};
this.renderTime = function () {
var timeDiff = new Date() - this.startTime + this.startDiff;
this.timeDiff = timeDiff;
timeDiff /= 1000;
// get seconds
this.seconds = Math.round(timeDiff % 60);
// remove seconds from the date
timeDiff = Math.floor(timeDiff / 60);
// get minutes
this.minutes = Math.round(timeDiff % 60);
// remove minutes from the date
timeDiff = Math.floor(timeDiff / 60);
// get hours
this.hours = Math.round(timeDiff % 24);
this.block.innerHTML = this.hours + " h " + this.minutes + " min " + this.seconds + " sec";
// window.setInterval('this.obName.renderTime()',1000);// Uncomment if you want to test your PCs limit
};
this.renderButtons = function () {
var timePassed;
//this.parentTimer = document.getElementsByClassName("timer "+this.obName)[0];
this.startButton = document.createElement("INPUT");
this.startButton.setAttribute("type", "button");
this.startButton.setAttribute("value", "start");
this.startButton.className = "start " + this.obName;
this.stopButton = document.createElement("INPUT");
this.stopButton.setAttribute("type", "button");
this.stopButton.setAttribute("value", "stop");
this.stopButton.className = "stop " + this.obName;
this.placeholder.insertBefore(this.startButton, this.block);
this.placeholder.insertBefore(this.stopButton, this.block);
this.startButton.addEventListener("click", function () {
//if (this.hours === 0 && this.minutes === 0 && this.seconds === 0){
self.startTime = new Date();
// }
tm = window.setInterval(self.renderTime.bind(self), 1000);
});
this.stopButton.addEventListener("click", function () {
window.clearInterval(tm);
self.startDiff = self.timeDiff;
console.log(':', self, self.startDiff);
//timePassed = this.endTime - this.startTime;
//endTime = new Date();
// timePassed = endTime - startTime;
});
//give listener to clear and start interval
};
}
function createNewTimer() {
obName = document.getElementById("ObName").value;
if (obName !== "") {
obName = new TimerObject(obName);
obName.addBlock();
obName.renderButtons();
obName.renderTime();
//window.setInterval('obName.renderTime()',1000);
} else {
document.getElementById("ObName").value = "Fill me";
}
}
There were several issues with the code:
1. Some functions weren't being bound to the correct context (this).
2. The reference set to "obName" was global and constantly changing to the newly created instance.
3. The start time variable was global and constantly being reset every time you called the renderTime function.
I have made the modifications to your code in jsFiddle and they can be found in this update: http://jsfiddle.net/3qxoea52/5/
Rendering:
this.renderTime = function (startTime) {
if( startTime ) {
this.startTime = startTime;
}
this.endTime = new Date();
// time difference in ms
this.timeDiff = this.endTime - this.startTime;
// strip the miliseconds
this.timeDiff /= 1000;
// get seconds
this.seconds = Math.round(this.timeDiff % 60);
// remove seconds from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get minutes
this.minutes = Math.round(this.timeDiff % 60);
// remove minutes from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get hours
this.hours = Math.round(this.timeDiff % 24);
this.block.innerHTML = this.hours + " h " + this.minutes + " min " + this.seconds + " sec";
// window.setInterval('this.obName.renderTime()',1000);// Uncomment if you want to test your PCs limit
}
Binding:
this.startButton.addEventListener("click", function () {
//if (this.hours === 0 && this.minutes === 0 && this.seconds === 0){
this.startTime = new Date();
// }
this.tm = window.setInterval(this.renderTime.bind(this), 1000);
}.bind(this))
this.stopButton.addEventListener("click", function () {
window.clearInterval(this.tm);
//timePassed = this.endTime - this.startTime;
//endTime = new Date();
// timePassed = endTime - startTime;
}.bind(this))
CreateTimer:
function createNewTimer() {
obName = document.getElementById("ObName").value;
if (obName !== "") {
obName = new timerObject(obName);
obName.addBlock();
obName.renderButtons();
startTime = new Date();
obName.renderTime(startTime);
//window.setInterval('obName.renderTime()',1000);
} else {
document.getElementById("ObName").value = "Fill me";
}
};