I have a timer ticker on Layout(MVC4.0) (With 1 Second Interval) page and it works fine when only 1 page of website(In one tab) is opened
var timeOutMinutes = 10;
var timeOutSeconds = timeOutMinutes * 60;
localStorage.setItem("SessionCounter", timeOutSeconds);
var popUpShown = false;
var logOutCalled = false;
$(document).ready(function () {
setInterval(TimerDecrement, 1000);
});
function TimerDecrement() {
if (timeOutSeconds > 0) {
if (parseInt(localStorage.getItem("SessionCounter"), 10) > 0) {
timeOutSeconds = parseInt(localStorage.getItem("SessionCounter"), 10);
}
timeOutSeconds--;
localStorage.setItem("SessionCounter", timeOutSeconds);
}
else {
if (!logOutCalled) {
logOutCalled = true;
LogOut();
}
else {
logOutCalled = true;
}
}
document.getElementById("seconds").innerHTML = timeOutSeconds;
document.getElementById("secondsIdle").innerHTML = timeOutSeconds;
if (timeOutSeconds < 500) {
//alert(history.length);
popUpShown = true;
$("#pnlPopup").dialog("open");
}
else {
if ($("#pnlPopup").dialog("isOpen")) {
popUpShown = false;
$("#pnlPopup").dialog("close");
}
}
}
But when I open multiple tabs of website timer jumps to decrease quickly.
How can I maintain the timer to decrement Uniformly even if website is opened in multiple tabs?
FIDDLE
The problem is that you are using the counter that is being decremented is common to all tabs, because it is kept in LocalStorage. So the solution really depends on what you intention is for the decrement counter.
If the intention is for each session (each tab) to have it's own separate counter, then you would be better served using a variable instead of LocalStorage -- or alternatively, use a unique session id for each counter in LocalStorage.
If the intention is to have all tabs share the same decrement counter, but for it to only be decremented once per second regardless of how many tabs are open, then perhaps you want to store the counter as well as the last decrement time.
EDIT: Here is a forked fiddle that might do what you need:
http://jsfiddle.net/y68m4zwr/8/
The gist of it is to add:
var lastUpdated = localStorage.getItem("SessionCounterUpdatedOn"),
now = new Date(), shouldCheck = false;
if (lastUpdated == null) {
localStorage.setItem("SessionCounterUpdatedOn", now);
} else if (now.getTime() - new Date(lastUpdated).getTime() >= 1000) {
// set this immediatedly so another tab checking while we are processing doesn't also process.
localStorage.setItem("SessionCounterUpdatedOn", now);
shouldCheck = true;
}
which checks for a last updated record for the counter and it if was updated less that second ago, it just updates the time left, otherwise performs the logic to decrement.
Related
I can't for the life of my figure out how to get this to work bug free.
The button in the code below needs to do three things.
Start a countdown when clicked (works)
End the countdown automatically, and reset itself when it reaches 0(works)
Reset itself prematurely if its clicked in the middle of a countdown(works, sort of)
Bug: when clicked repeatedly it starts multiple countdowns, and more or less breaks. It needs to either reset itself or start a countdown if clicked repeatedly. There should never be more than one countdown.
It works fines as long as people press the button, wait a second, and then press it again to stop it.
The bug I'm running into is if someone spam clicks it, it starts multiple countdowns and generally just breaks the button. I've tried a lot of different methods to fix it, and this is the closest I've gotten.
var i = 29;
let running=false;
$("#startButton").click(function () {
if(running==false){
var countdown = setInterval(function () {
$("#startButton").text("Reset Timer");
running=true;
$("#stopWatch").html(i);
i--;
if (i <0)
{
$("#startButton").text("Start Timer");
running=false;
clearInterval(countdown);
i = 29;
$("#stopWatch").html(i);
}
$("#startButton").click(function () {
$("#startButton").text("Start Timer");
running=false;
clearInterval(countdown);
i = 29;
$("#stopWatch").html(i+1);
});
}, 1000);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="stopWatch">30</div>
<button id="startButton">Start Timer</button>
Welcome to Stack Overflow #William!
I'm not sure what this means: Reset itself prematurely if its clicked in the middle of a countdown(works, sort of). But I managed to fix your bug on spamming button click and for item 3, i just do reset the countdown from initial state. See snippets below:
// Get attribute value from div `stopwatch`. This is for resetting from default value.
var initial = $('#stopWatch').attr("value");
// Assigned initial value to var i.
var i = initial;
$("#stopWatch").html(i);
let running = false;
// Created a separate function to call from button click.
function run(timer = true) {
if (timer) {
running = true;
$("#startButton").text("Reset Timer");
$("#stopWatch").html(i);
var countdown = setInterval(function () {
i--;
$("#stopWatch").html(i);
if (i <= 0) {
running = false;
$("#startButton").text("Start Timer");
clearInterval(countdown);
i = initial;
$("#stopWatch").html(i);
}
}, 1000);
} else {
running = false;
clearInterval(countdown);
i = 0;
$("#startButton").text("Start Timer");
}
}
$("#startButton").click(function () {
// Check if its not running and var i is not 0
if(!running && i != 0) {
run();
// Check if its running and var i is not 0 to ensure that if someone spam the button it just reset the countdown.
} else if (running && i != 0) {
// Will return the else{} on function run().
run(false);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="stopWatch" value="30"></div>
<button id="startButton">Start Timer</button>
Added some comments on the snippet. Feel free to ask if you have any questions.
I'm looking to update a number on a success page and permanently change the number so that new visitors get the updated number. The site is build in Wordpress. The route with localStorage would not work as the updated number is then not visible to new visitors.
Do you have a solution how to update the ID element permanently? Do I need to use a PHP function?
window.addEventListener('load', function () {
let signUpCounter = document.querySelector("#sign-up-counter");
if (signUpCounter) {
function countUpByOne(start, end) {
var current = start;
setInterval(function () {
// current += 1;
current++;
signUpCounter.innerHTML = current;
if (current == end) {
current = start;
}
}, 10000);
}
}
countUpByOne(7000, 15000);
});
Many thanks for your help!
I'm trying the make a chrome extension in javascript. So far, my popup.js looks like this:
let bg;
let clock;
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('button1').addEventListener('click', butClicked);
bg = chrome.extension.getBackgroundPage();
//clock = document.getElementById("label1");
});
let timeStamp;
let isClockRunning = false;
function butClicked() {
let test = bg.getURL();
document.getElementById('test').innerHTML = test;
timeStamp = new Date();
isClockRunning = !isClockRunning;
runCheckTimer();
}
function runCheckTimer() {
var handle;
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}
function updateClock() {
let seconds = bg.returnTimeSince(timeStamp);
document.getElementById("label1").innerHTML = "Seconds: " + seconds;
}
The program works just fine when I click the button once; it starts the timer. But when I click the button the second time, timeStamp gets set to 0, but the updateClock keeps running at the same interval; the interval doesn't get cleared even though I'm toggling the isClockRunning boolean. It's almost as if javascript is forgetting to run the else if part in runCheckTimer(). How can I fix this?
EDIT: On a sidenote, am I doing the timer thing the right way? Or is there a better way to do it? I basically want a timer to keep ticking every second since you've pressed the button, and then when you click it again it'll stop and reset to 0.
You have scoped handle to runCheckTimer. When runCheckTimer starts, it will create a new handle every time.
Move handle outside of the function.
var handle;
function runCheckTimer() {
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}
I'm having issues with my JavaScript code. I need to make code that does the following:
Click an image twice within 3 seconds to make the image disappear
Click it once to reappear
I've got it close to working...I'm just having issues with the date. I don't know how to keep the date from the first click. My code right now is just creating a new start date each click which is what I don't want.
Code thus far:
var imgNext = -1;
var start = new Date ( );
function disappear ()
{
var end = new Date ();
imgNext++;
if (imgNext == 2)
{
document.getElementById("myPicture").style.visibility="visible";
imgNext = -1;
}
if (imgNext == 1 && (end-start <3000))
{
document.getElementById("myPicture").style.visibility="hidden";
}
start = new Date ();
}
In the code the image changes even if the clicks are over 3 seconds apart because I'm creating a new START date every time the function is triggered. How do I resolve this?
Here is answer, with a working example: http://jsfiddle.net/yS5bs/2/
document.getElementById("disappear").onclick = function() {
var lastClick = this.attributes["click-time"],
click = new Date().getTime(),
timeout = parseInt(this.attributes["data-timeout"].value);
if(lastClick && (click - lastClick) < timeout && this.style.opacity == 1) {
this.style.opacity = 0;
this.attributes["click-time"].value = null;
return;
}
else {
this.attributes["click-time"] = click;
}
if(this.style.opacity == 0) {
this.style.opacity = 1;
this.attributes["click-time"] = null;
return;
}
};
basically I am assigning the onclick, and getting the click times, if within the set timeout (milliseconds) then it hides, otherwise, it shows again, as per spec
My progress bar loader which i'm using to display a sorten amount of seconds while my page is loading in Javascript is having some trouble.
If i click another tab while its counting it will pause, and will only resume when you go back.
How would i go by allowing it to count even though you're in another tab
$(document).ready(function() {
if(!Modernizr.meter){
alert('Sorry your brower does not support HTML5 progress bar');
} else {
var progressbar = $('#progressbar'),
max = progressbar.attr('max'),
time = (800/max)*10,
value = progressbar.val();
var loading = function() {
value += 1;
addValue = progressbar.val(value);
$('.progress-value').html(value + '%');
if (value == max) {
clearInterval(animate); $(".demo-wrapper").remove(); $("#details").fadeIn("slow"); $("#motion1").html("Report for Registration."); $("#motion").remove();
}
if (value == 1) {
$("#motion").html("Loading Page..");
}
if (value == 86) {
$("#motion").html("Connecting..");
}
};
var animate = setInterval(function() {
loading();
}, time);
};
});
Here's an example http://jsfiddle.net/w977Q/
Maybe have a look at the accepted answer here: How can I make setInterval also work when a tab is inactive in Chrome?
It appears this is basically a function of the browser not wanting to use processing power on tabs that aren't in focus.
Hope this helps you
setInterval('yourFunction();', 1000); // this will work even on other tab
and
setInterval(yourFunction, 1000); // this will run only if on current tab