Reset JS timer when window goes out of focus - javascript

Been twisting my head for a long time over this and can't seem to get it to work.
Basically trying to reset the timer when the window goes out of focus for longer than 30 seconds.
I'd be thankful for any solution that works.
Regards, Will.
window.onData = function(data) {
if (data.setDisplay == true) {
$("#container").css('display', 'flex');
$("body").fadeIn(1000);
var counter = 90;
var c = 90;
var i = setInterval(function(){
$(".loading-page .counter h1").html("YOU HAVE " + c + " SECONDS LEFT UNTIL RESPAWN");
$(".loading-page .counter hr").css("width", c + "");
counter--;
c--;
if(counter == 0) {
$(".loading-page .counter h1").html("YOU MAY DO /RESPAWN");
$(".loading-page .counter p").html("DON'T FORGET THE NEW LIFE RULE!");
clearInterval(i);
}
}, 1000);
} else {
$("#container").css('display', 'none');
$("body").css('display', 'none');
}
}
window.onload = function(e) {
window.addEventListener('message', function(event) {
onData(event.data)
});
}

Perhaps you mean this?
Not tested but has enough snippets to be moved around
const onData = function(data) {
if (data.setDisplay == true) {
$("#container").css('display', 'flex');
$("body").fadeIn(1000);
let tId = setInterval(function() {
$(".loading-page .counter h1").html("YOU HAVE " + counter + " SECONDS LEFT UNTIL RESPAWN");
$(".loading-page .counter hr").css("width", counter);
counter--;
if (counter == 0) {
$(".loading-page .counter h1").html("YOU MAY DO /RESPAWN");
$(".loading-page .counter p").html("DON'T FORGET THE NEW LIFE RULE!");
clearInterval(tId);
}
localStorage.setItem("counter",counter);
}, 1000);
} else {
$("#container").hide()
$("body").hide()
}
}
let counter;
const getCounter = function() {
counter = localStorage.getItem("counter");
counter = counter === null ? 90 : +counter; // continue from where it was
const now = new Date().getTime()
const blurred = sessionStorage.getItem("blurred");
blurred = blurred ? +blurred : 0;
if (blurred && (now-blurred)/1000) >30) counter = 0;
};
$(function() {
$(window).on('message', function(event) {
onData(event.data)
});
$(window).on("blur",function() {
sessionStorage.setItem("blurred",new Date().getTime())
})
});
$(window).on("focus",getCounter )

Related

Having issue resetting JS stopwatch

I made a little typing game that reveals some random text and you have to type the same in, so that you can test your typing speed. the users has the ability to play again and again, the issue is that when the user types play again, the stopwatch does not begin as it did the first time.
Can anyone help me with making the stopwatch restart everytime the user clicks on the play again button?
[ full code is here] (https://jsfiddle.net/kisho/ncbxd9o4/#&togetherjs=qD5bT8vLiw)
js portion-
const textDisplay = document.querySelector('#text-display');
const input = document.querySelector('#input');
const btn = document.querySelector('#btn');
const textBox = document.querySelector('#text-box');
const countdown = document.querySelector('#countdown');
const stopwatch = document.querySelector('#stopwatch');
const successMessege = document.querySelector('#success-messege');
const stopwatchTime = document.querySelector('#stopwatch-time');
btn.addEventListener('click', runGame);
function runGame() {
if ((btn.innerText = 'Play again')) {
playAgain();
fetchQuote();
countownTimer();
confirmQuote();
} else {
fetchQuote();
countownTimer();
confirmQuote();
}
}
function fetchQuote() {
fetch('https://api.quotable.io/random')
.then((res) => {
return res.json();
})
.then((data) => {
textDisplay.innerText = data.content;
});
}
function countownTimer() {
if (timer !== undefined) {
clearInterval(timer);
}
var timeleft = 2;
var downloadTimer = setInterval(function() {
if (timeleft <= 0) {
clearInterval(downloadTimer);
document.getElementById('countdown').innerHTML = 'Start Typing!';
input.classList.remove('displayNone');
runningStopwatch.classList.remove('displayNone');
begin();
} else {
document.getElementById('countdown').innerHTML = timeleft + ' seconds remaining';
}
timeleft -= 1;
}, 1000);
}
function confirmQuote() {
if ((countdown.innerHTML = 'Start typing!')) {
input.addEventListener('keyup', function(event) {
if (event.keyCode === 13) {
if (textDisplay.innerText === input.value) {
btn.innerText = 'Play again';
// textBox.classList.add('displayNone');
hold();
} else successMessege.innerText = 'Missed something there, try again!!';
}
});
}
}
function playAgain() {
textBox.classList.remove('displayNone');
input.classList.add('displayNone');
input;
input.value = '';
successMessege.innerText = '';
}
let ms = 0,
s = 0,
m = 0;
let timer;
let runningStopwatch = document.querySelector('.running-stopwatch');
function begin() {
timer = setInterval(run, 10);
}
function run() {
runningStopwatch.textContent =
(m < 10 ? '0' + m : m) + ': ' + (s < 10 ? '0' + s : s) + ': ' + (ms < 10 ? '0' + ms : ms);
ms++;
if (ms == 100) {
ms = 0;
s++;
}
if (s == 60) {
s = 0;
m++;
}
}
function hold() {
clearInterval(timer);
successMessege.innerText = `Nice job! You just typed in x seconds!`;
}
function stop() {
(ms = 0), (s = 0), (m = 0);
runningStopwatch.textContent =
(m < 10 ? '0' + m : m) + ': ' + (s < 10 ? '0' + s : s) + ': ' + (ms < 10 ? '0' + ms : ms);
}
You are not handling the clearInterval correctly.
You are clearing the interval only if one ends the game successfully.
My solution would be:
When calling the countownTimer() function, the first thing you should do, is to check if the interval timer is still running.
function countownTimer() {
if (timer !== undefined) {
clearInterval(timer);
}
// [...]
}
The next thing would be, to start the interval every time begin() gets called.
function begin() {
timer = setInterval(run, 10);
}

My JQuery count down is not working perfectly,

I want to make a jQuery timer count down. It should have days, day, month, hours, seconds. I used this below code, but it is not working. When the browser is refreshed, the counter is restarting. Please help me to correct this code.
This is the jsFiddle
https://jsfiddle.net/saifudazzlings/LfLdo381/
The js code:
var sec = 60;
var min = 100;
var hr = 24;
var updateTimer = function() {
var timer = localStorage.getItem('timer') || 0;
var timermin = localStorage.getItem('timermin') || 0;
var timerhr = localStorage.getItem('timerhr') || 0;
$("div#timermin").html(timermin);
$("div#timerhr").html(timerhr);
if (timer === 0) {
$("div#timer").html("00");
} else if (timer <= 1) {
timer--;
timermin--;
localStorage.setItem('timermin', timermin);
$("div#timermin").html(timermin);
if (timermin < 1) {
if (timerhr == 0) {
localStorage.removeItem('timermin', timermin);
$("div#timermin").html("00");
localStorage.removeItem('timer', timer);
$("div#timer").html("00");
localStorage.removeItem('timerhr', timerhr);
$("div#timerhr").html("00");
} else {
timerhr--;
localStorage.setItem('timerhr', timerhr);
$("div#timerhr").html(timerhr);
localStorage.setItem('timermin', min);
$("div#timermin").html(timermin);
}
//timerhr--;
//localStorage.setItem('timerhr', timerhr);
//$("div#timerhr").html(timerhr);
//localStorage.setItem('timermin', min);
//$("div#timermin").html(timermin);
}
localStorage.setItem('timer', sec);
$("div#timer").html(timer);
} else {
timer--;
localStorage.setItem('timer', timer);
$("div#timer").html(timer);
if (timermin == 0) {
localStorage.removeItem('timer', timer);
$("div#timer").html("00");
$("div#countermessage").html("00");
}
}
};
$(function() {
$("#start").click(function() {
localStorage.setItem('timer', sec);
});
$("#start2").click(function() {
localStorage.setItem('timermin', min);
localStorage.setItem('timerhr', hr);
});
setInterval(updateTimer, 1000);
$(window).load(function() {
localStorage.setItem('timer', sec);
localStorage.setItem('timermin', min);
localStorage.setItem('timerhr', hr);
});
});

call EventListener with setInterval()

My task is to make a few pictures in a slideshow and if don't click a button for forward and back (id = right and id = left in my code) in 5 seconds it should automaticly move forward , i succeeded but i feel that the code is to much.
var counter = 1;
$('#left').on('click', function peter() {
clearInterval(time);
time = setInterval(function () {
var id = '#' + counter;
$(id).attr('class', 'hidden');
counter++;
if(counter === 4){
counter = 1;
}
id = '#' + counter;
$(id).attr('class', 'visible');
},3000);
var id = '#' + counter;
$(id).attr('class', 'hidden');
counter--;
if (counter === 0) {
counter = 3;
}
id = '#' + counter;
$(id).attr('class', 'visible');
});
$('#right').on('click', function () {
clearInterval(time);
time = setInterval(function () {
var id = '#' + counter;
$(id).attr('class', 'hidden');
counter++;
if(counter === 4){
counter = 1;
}
id = '#' + counter;
$(id).attr('class', 'visible');
},3000);
var id = '#' + counter;
$(id).attr('class', 'hidden');
counter++;
if(counter === 4){
counter = 1;
}
id = '#' + counter;
$(id).attr('class', 'visible');
});
var time = setInterval(function peter() {
var id = '#' + counter;
$(id).attr('class', 'hidden');
counter++;
if(counter === 4){
counter = 1;
}
id = '#' + counter;
$(id).attr('class', 'visible');
},3000);
So the problem as you can see is that i pretty much decleared my setInterval() 3 times, 1st in my code and then i declear it every time in my eventListeners to reset it. My question is this: Is there any way to declear it once and call the eventListeners like time(call listnener for id='right') and then in the event listners to just reset it like clearInterval(a); without having to retype it.
var counter = 1;
var time;
function intervalFunction(offset)
{
var id = '#' + counter;
$(id).attr('class', 'hidden');
counter += offset;
if(counter > 4)
counter = 1;
else if(counter < 1)
counter = 4;
id = '#' + counter;
$(id).attr('class', 'visible');
}
function startInterval(offset){
if(time)
clearInterval(time);
intervalFunction(offset);
time = setInterval(function () {
intervalFunction(1);
},3000);
}
$('#left').on('click', function peter() {
startInterval(-1);
});
$('#right').on('click', function () {
startInterval(1);
});
startInterval(1);
I'm not sure if this would do it. Didn't actually test it first. But you could combine all of the redundant work into a single function that you would call. I added the clicktype parameter to the function and use it to determine if it should increment or decrement the value of counter.
I also modified the setInterval to setTimeout, as in this setup the call is cleared and reset each time anyway.
var counter = 1;
var timeoutdelay = 3000;
function OnChangeSlide(clicktype) {
clearTimeout(time);
var id = '#' + counter;
$(id).attr('class', 'hidden');
counter = counter + (clicktype=='#left' ? -1 : 1);
if (counter === 0) {
counter = 3;
} else if (counter === 4) {
counter = 0;
}
id = '#' + counter;
$(id).attr('class', 'visible');
time = setTimeout(function() { OnChangeSlide('#right'); }, timeoutdelay);
}
$('#left').on('click', function() { OnChangeSlide('#left'); } );
$('#right').on('click', function() { OnChangeSlide('#right'); } );
time = setTimeout(function(){ OnChangeSlide('#right'); }, timeoutdelay);

Clear setTimeout()

I have a list of videos, if the user clicks on one video then clicks on a second video before the first one has finished, the timer keeps going and second video changes when it shouldn't. I have tried using clearTimeout to stop the first video timer but it isn't doing anything.
var last_div = 0;
function getVid(div_num, vid_length, count, id)
{
clearTimeout(timer1)
time_limit = vid_length * 1000 + 4000; //plus 4000 is to account for the lagging of the youtube video loading
if(last_div == 0)
{
last_div = div_num;
document.getElementById("vid_div" + div_num).style.background="#DCE4EB";
}
else
{
document.getElementById("vid_div" + last_div).style.background="";
last_div = div_num;
document.getElementById("vid_div" + div_num).style.background="#DCE4EB";
}
player.loadVideoById(id);
player.setVolume(20);
if(div_num != count)
{
div_num++;
var timer1 = setTimeout(function(){
document.getElementById("vid_div" + div_num).onclick();
},
time_limit);
}
else
{
setTimeout(function(){
document.getElementById("vid_div" + div_num).style.background="";
},
time_limit);
}
}
var timer1 is a local variable. That is one of your problems. The other problem is the other setTimeout does not have a variable.
Change it to:
var last_div = 0,timer1;
function getVid(div_num, vid_length, count, id)
{
clearTimeout(timer1)
time_limit = vid_length * 1000 + 4000; //plus 4000 is to account for the lagging of the youtube video loading
if(last_div == 0)
{
last_div = div_num;
document.getElementById("vid_div" + div_num).style.background="#DCE4EB";
}
else
{
document.getElementById("vid_div" + last_div).style.background="";
last_div = div_num;
document.getElementById("vid_div" + div_num).style.background="#DCE4EB";
}
player.loadVideoById(id);
player.setVolume(20);
if(div_num != count)
{
div_num++;
timer1 = setTimeout(function(){
document.getElementById("vid_div" + div_num).onclick();
},
time_limit);
}
else
{
timer1 = setTimeout(function(){
document.getElementById("vid_div" + div_num).style.background="";
},
time_limit);
}
}

clearInterval is not clearing

Take a look at the function below, It purpose is to change the button text
to "Abort", "Abort 0", "Abort 1" and so on.
Once the counter reaches 10 another function should be executed, but if
the button is clicked, the counter should stop, and the button text should return
to it's original value ("Sync DB").
It seems I'm trying to clear out the interval in a wrong way.
Any assistance will be appreciated.
function sync_database(abort)
{
if (abort == true) { sync_db_btn.innerHTML = "Sync DB"; return false }
sync_db_btn.innerHTML = "Abort"
var i = 0;
sync_db_btn.addEventListener("click", function() { sync_database(true) } );
var x = setInterval(function() {
if (abort == true) {
clearInterval(x);
}
if (i < 10) {
sync_db_btn.innerHTML = "Abort " + i++;
}
}, 1000);
}
var x;
sync_db_btn.addEventListener("click", function() {
sync_database(true);
clearInterval(x);
} );
function sync_database(abort)
{
if (abort == true) { sync_db_btn.innerHTML = "Sync DB"; return false }
sync_db_btn.innerHTML = "Abort"
var i = 0;
x = setInterval(function() {
if (i < 10) {
sync_db_btn.innerHTML = "Abort " + i++;
}
}, 1000);
}
I think you need something like this:
var sync_db_btn = document.getElementById('but'),
abortSync = -1,
interval,
sync_database = function () {
var i = 0;
abortSync *= -1;
if (abortSync < 0) {
sync_db_btn.innerHTML = 'Sync DB';
clearInterval(interval);
return false;
}
sync_db_btn.innerHTML = 'Abort';
interval = setInterval(function () {
if (i < 10) {
sync_db_btn.innerHTML = 'Abort ' + i++;
} else {
sync_db_btn.innerHTML = 'Sync DB';
clearInterval(interval);
abortSync = -1;
}
}, 1000);
};
sync_db_btn.addEventListener('click', sync_database);
A live demo at jsFiddle.

Categories