I am doing a timer that I store in a sessionStorage but if a refresh the page the timer stop! some help please
function time (secondes) {
const temps = Date.now();
const apres = temps + secondes * 1000;
const timer = setInterval(() => {
const secondsLeft = Math.round((apres - Date.now()) / 1000)
if (secondsLeft < 0) {
clearInterval(timer);
sessionStorage.clear();
if (sessionStorage.getItem('Timer') === null) {
$(".reservation").css("display", "none");
}
return;
}
sessionStorage.setItem("Timer", secondsLeft)
}, 1000);
}
the getItem("timer") here is just to check if the timer is over, I am using this Timer item in another method
thx
SessionStorage persist even if the page reloads. Read this:https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage
What you should do is, after you refresh the page, get the value of Timer again from SessionStorage and then again call the method.
function time (secondes) {
const temps = Date.now();
const apres = temps + secondes * 1000;
const timer = setInterval(() => {
const secondsLeft = Math.round((apres - Date.now()) / 1000)
if (secondsLeft <= 0) {
clearInterval(timer);
sessionStorage.clear();
//you dont need below if condition as secondsLeft is already 0. Commented if condition.
//if (sessionStorage.getItem('Timer') === null) {
$(".reservation").css("display", "none");
//}
return;
}
else{
//update the div content and show the current timer value in the div or in the span inside the div. (write a separate function for this).
}
sessionStorage.setItem("Timer", secondsLeft)
}, 1000);
}
//Method to call after page load:
function startTimerOnPageLoad(){
var x = parseInt( sessionStorage.getItem('Timer'));
//put a check, Timer is present in sessionStorage and x is not undefined. I've not added it here purposely.
time(x);
}
Related
I use this function with cache to make if the user enter the site for first time in last
x minutes redirect him and if this is the second time press the button i now want to add if this is the third time in last x minutes to do another thing.
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(";").shift();
}
function setLastAccess() {
const date = new Date();
const expireMs = 0.5 * 60 * 1000; // number of minutes
date.setTime(date.getTime() + expireMs);
document.cookie = `lastAccess=${new Date().getTime()};expires=${date.toUTCString()};path=/`;
}
if (!getCookie('lastAccess')) {
window.location.href = "http://google.com";
setLastAccess(); // set your last access at the end
} else {
setTimeout(function() {
document.getElementById('button-login').click();
}, 1000);
}
You can maintain a counter in localStorage whenever user access the site, and update it. Check for the count and if it is 3, run your logic.
You can also store it in cookie if it needs to be transferred to server.
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(";").shift();
}
function setLastAccess() {
const date = new Date();
const expireMs = 0.5 * 60 * 1000; // number of minutes
date.setTime(date.getTime() + expireMs);
document.cookie = `lastAccess=${new Date().getTime()};expires=${date.toUTCString()};path=/`;
}
function numAccess() {
if(!localStorage.getItem('accessCount')) {
localStorage.setItem('accessCount', '1');
} else {
localStorage.setItem(+localStorage.getItem('accessCount') + 1)
}
}
if (!getCookie('lastAccess')) {
window.location.href = "http://google.com";
setLastAccess(); // set your last access at the end
numAccess();
} else {
setTimeout(function() {
numAccess();
document.getElementById('button-login').click();
}, 1000);
}
if(+localStorage.getItem('accessCount') === 3) {
// Do some stuff
}
I need to print a console in every 20 second(technically i will call a action in reactjs) inside a interval which is running in every second.
this is a dummy code not functioning properly.
var intervalDuration = 200;
var hitOnEvery = 20;
setInterval(() => {
interValDuration -= 1;
if (interValDuration >= 0) {
setTimeout(()=>{
console.log(interValDuration , 'Hit on every' + hitOnEvery + 'second')
},hitOnEvery);
}
console.log('This will print every '+intervalDuration +'count in a place')
}, 1000);
can someone correct and help me.
You can do it like this:
var interValDuration = 200;
var hitOnEvery = 20;
setInterval(() => {
interValDuration -= 1;
if (interValDuration % hitOnEvery == 0) {
console.log(interValDuration , 'Hit on every' + hitOnEvery + 'second')
}
console.log('This will print every '+interValDuration +'count in a place')
}, 1000);
Basically check if interValDuration divided by hitOnEvery has 0 leftover after division, meaning every 20sec perform action
Here is the closure function, for the generic usage
const timer = (() => {
let timer;
let seconds = 1;
return (func, hitAtTime) => {
let stopTimer = () => {
console.log(timer);
window.clearInterval(timer);
};
const startTimer = () => {
timer = window.setInterval(() => {
console.log("i run every second");
seconds++;
if (seconds % hitAtTime === 0) {
func();
}
}, 1000);
};
return {
stopTimer: stopTimer,
startTimer: startTimer,
};
};
})();
timer(() => console.log("i run every 10 seconds"), 10).startTimer();
I've came across with an interesting event.
I'm trying to build a pomodoro timer that runs in the background with an alarm that fires when the timer finishes and starts.
I coded a WebWorker Script that runs that same timer.
worker.js
self.addEventListener("message", (e) => {
if (e.data.task === 'run the timer') {
currentTimeLeftInSession = e.data.defaultWorkTime;
countdown = setInterval(() => {
currentTimeLeftInSession--;
currentTimeLeftInSessionBackwards++;
if(currentTimeLeftInSession < 0) {
return;
}
let timeLeft = getTimeLeft(currentTimeLeftInSession);
let data = {
'timeLeft': timeLeft,
}
self.postMessage(data);
}, 1000);
}
function getTimeLeft(seconds) {
let minutes = Math.floor(seconds / 60);
let remainderSeconds = Math.floor(seconds % 60);
let timeLeft = `${minutes}:${remainderSeconds}`;
if (remainderSeconds < 10) {
timeLeft = `${minutes}:0${remainderSeconds}`;
if (minutes < 10) {
timeLeft = `0${minutes}:0${remainderSeconds}`;
}
}
return timeLeft;
}
})
And added an event listener to the pomodoro script that updates the timer display
pomodoro.js
let worker = new Worker('/lib/js/worker.js')
worker.addEventListener('message', (e) => {
progressBar.text.innerText = e.data.timeLeft;
console.log(e.data.timeLeft)
if(e.data.timeLeft == '00:00') {
playAudio(audioNumber);
}
});
startButton.addEventListener('click', () => {
defaultWorkTime = 200
let data = {
'task': 'run the timer',
'defaultWorkTime': defaultWorkTime,
'defaultBreakTime': defaultBreakTime,
}
worker.postMessage(data);
});
The interesting thing here:
If i remove the console.log the timer stops getting updated. If i set it all goes with the plan.
Why does this happen???
Is there a way that the timer doesn't stop after couple of seconds if it's running on background?
I've got a user which i get from database. For each user is possible to reset his password. But it's possible only one time for three minutes. If password was reseted less than three minutes, I show timer with JS, which show how much time left for next reset and reset button is disabled. When countdown is finished, button become availiable and displayed inscription "Password reset avaliable". Because the each user has his own timer, when I select another user, previous timer must be stopped with reset() function, and must be started other timer. It's just the only one timer must be in one time.
Timer:
var timerCount = 0;
function startTimer(minute, second) {
timerCount++;
start(minute, second);
}
function start(minute, second) {
disableButton('resetPasswordButton');
var m = minute;
var s = second;
if (timerCount == 0) {
document.getElementById('expiredTimeOutputText').innerHTML = "Password reset avaliable";
m = 0;
s = 0;
enableButton('resetPasswordButton');
return ;
}
if (s == 0) {
if (m == 0) {
reset();
document.getElementById('expiredTimeOutputText').innerHTML = "Password reset avaliable!";
enableButton('resetPasswordButton');
return ;
}
m--;
s = 59;
} else
s--;
document.getElementById('expiredTimeOutputText').innerHTML = m + ":" + s;
setTimeout(function () {
start(m, s);
}, 1000);
}
function reset() {
if (timerCount > 0) {
timerCount = 0;
}
}
function enableButton(id){
document.getElementById(id).disabled = false;
}
function disableButton(id){
document.getElementById(id).disabled = true;
}
method to start timer on button click
public void changePassword() {
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.execute("startTimer(\"0\", \"40\")");
Date tmpDate = new Date();
Long diff = tmpDate.getTime();
mainDataBean.setResetTimer(applicantsTableSelectedRow.get("ID"), diff.toString());
}
method to start timer on user change
public void checkTimerForNewUser() {
RequestContext requestContext = RequestContext.getCurrentInstance();
Date tmpDate = new Date();
Long currentTime = tmpDate.getTime();
requestContext.execute("reset()");
if (applicantsTableSelectedRow != null) {
if (!mainDataBean.getResetTimer(applicantsTableSelectedRow.get("ID")).equals("noTimer")) {
Long applicantTimerTime = Long.parseLong(mainDataBean.getResetTimer(applicantsTableSelectedRow.get("ID")));
if (currentTime - applicantTimerTime > timerValue) {
mainDataBean.deleteResetTimer(applicantsTableSelectedRow.get("ID"));
}
else {
expiredTimeMinute = (timerValue - (currentTime - applicantTimerTime)) / 60000;
expiredTimeSecond = (timerValue - (currentTime - applicantTimerTime)) / 1000 - expiredTimeMinute * 60;
requestContext.execute("startTimer(\"" + expiredTimeMinute + "\", \"" + expiredTimeSecond + "\")");
}
}
}
}
If consistently reset user password, one after another, everything works fine. But if I consistently reset password for 5 users, and after that I return to first user with reseted password, if time isn't expired, I've got all 5 timers, which overlap one another, display 5 different times 5 time in second. But in theory they must stop because of reset function. How does it possible to make the only one timer exist? Do I stop functions wrong?
Example with clearTimeout:
function start(minute, second) {
disableButton('resetPasswordButton');
var m = minute;
var s = second;
if (timerCount == 0) {
document.getElementById('expiredTimeOutputText').innerHTML = "Reset Button Available!";
clearTimeout(timeout);
enableButton('resetPasswordButton');
return ;
}
if (s == 0) {
if (m == 0) {
reset();
clearTimeout(timeout);
document.getElementById('expiredTimeOutputText').innerHTML = "Reset Button Available!";
enableButton('resetPasswordButton');
return ;
}
m--;
s = 59;
} else
s--;
document.getElementById('expiredTimeOutputText').innerHTML = m + ":" + s;
timeout = setTimeout(function () {
start(m, s);
}, 1000);
}
You can clear timers with:
clearTimeout for setTimeout
clearInterval for setInterval
Example:
// will *never* run since we clear it below, immediately after we
// create it.
var timeout = setTimeout(() => {
console.log('foo')
}, 1000)
clearTimeout(timeout)
// will run only *once* since we clear it when it's called
var interval = setInterval(() => {
console.log('bar')
clearInterval(interval)
}, 1000)
I have THIS timer in my project.
When it runs out, it shows a Time Up screen, which works fine.
But when the player is Game Over, i show the Game Over screen, but the timer keeps running and when it hits 00:00 then it switches to the Time Up screen.
How can i make this timer stop counting down and set to 00:00 again?
I tried adding a function like this:
CountDownTimer.prototype.stop = function() {
diff = 0;
this.running = false;
};
I also tried to change the innerHTML but its obvious that its just changing the numbers without stopping the timer and after a second it will show the count down again... I don't know what to call.
//Crazy Timer function start
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('#countDown'),
timer = new CountDownTimer(timerValue),
timeObj = CountDownTimer.parse(timerValue);
format(timeObj.minutes, timeObj.seconds);
timer.onTick(format).onTick(checkTime);
document.querySelector('#startBtn').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;
}
function checkTime(){
if(this.expired()) {
timeUp();
document.querySelector('#startBtn').addEventListener('click', function () {
timer.start();
});
}
}
};
Instead of recursively calling setTimeout, try setInterval instead. You could then store a reference to the timer:
this.timer = setInterval(functionToRunAtInterval, this.granularity);
and kill it when the game finishes::
clearInterval(this.timer)
(see MDN's docs for more info on setInterval)
It's been a while and I'm not sure if you've figured it out but check out the fiddle below:
https://jsfiddle.net/f8rh3u85/1/
// until running is set to false the timer will keep running
if (that.running) {
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);
}
I've added a button that causes running to be set to false which stops the timer.
Button:
<button id="stop">Game Over</button>
Code:
$( "#stop" ).click(function() {
timer.running = false;
});
So that should hopefully get you to where you need to be.
Similar to Tom Jenkins' answer, you need to cancel the next tick by avoiding the diff > 0 branch of your if statement. You could keep your code as it stands and use your suggested stop method, however, you'd need to change your logic around handling ticks to check that both running === true and a new param gameOver === false.
Ultimately, I think your problem is that no matter whether the timer is running or not, you'll always execute this code on a tick:
obj = CountDownTimer.parse(diff);
that.tickFtns.forEach(function(ftn) {
ftn.call(this, obj.minutes, obj.seconds);
}, that);
If you have a game over state, you probably don't want to call the provided callbacks, so add some conditional check in there.