I am trying to build a jQuery timer, but it stops when the browser is not focused or minimized. One of my thoughts is the code can use Ajax to pull data constantly from the server and update the timer, but my concern is that it may increase the pressure of the server. I wonder is there any way to check if user is using browser at frontend, so the code only needs to send Ajax request once the user returns.
My jQuery timer code snippet.
(function timer (offset) {
setTimeout(function () {
var timestamp = {{ time }};
timestamp = 5 * 60 - timestamp - offset;
var minutes = Math.floor(timestamp / 60);
var seconds = Math.floor(timestamp % 60);
document.getElementById("timer").innerHTML = minutes + " : " + seconds;
timer(offset + 0.5);
}, 500);
})(0);
window.setTimeout's delay parameter is the minimum amount of time before the callback runs, not a guaranteed time. Instead of keeping a running total of time elapsed in the timeout, store the time the timer started and compare it to the current time. Performance.now() will give you an accurate timestamp measured in milliseconds.
Related
I want to set timer every 5th minute. Example: timer countdown 5 minutes only at time 00:00 , 00:05 , 00:10 , 00:15 etc. in 00:17 timer should countdown 3 minutes
how setTimeout and setInterval with that provision?
I would like to do it programmatically, in React JS using javascript, anyone can help me?
When you want a function to run at a specific clock time, like every full minute, it's usually best to use setTimeout with sequential calls. That way you can work out the time to the next whole "tick" and set the timeout for that interval. This stops small lags caused by the system being busy accumulating, making the timing drift.
Using setInterval lags accumulate so the timing slowly drifts. The first run needs setTimeout anyway to start it at the right time (e.g. next full tick).
Here's a simple example to run a function on whatever tick you want, specified in milliseconds. The example is every 30 second tick but if you want 5 minutes just call it with 3e5 (i.e. 5 * 60 * 1000 = 300,000 which is the number of milliseconds in 5 minutes). Then it will run at the next full tick and every tick after that until cancelled.
setTimeout also returns an identifier (timer id, not used in the example) that you can use to stop it if necessary.
/**
* Run a function on every tick at specified interval. First
* call of fn is on next tick. May be a few ms late depending
* on system load when fn due to run.
*
* #param {Function} fn - function to call
* #param {number} tick - clock tick to run function on in milliseconds
* e.g. 30 secs = 3e4, 1 min = 6e4, 5 min = 3e5
*/
function onEveryTick(fn, tick) {
// Time to next tick
let getTick = () => tick - (Date.now() % tick);
// Currie function to sequentially call itself
let f = () => {
fn();
setTimeout(f, getTick());
}
// First call after required lag
setTimeout(f, getTick());
}
// Call on 30 second tick
onEveryTick(() => console.log('Tick ' + new Date().toString()), 3e4);
So i've got this problem,
For a score function I have that increases by one per second, it works in Google Chrome (version 53.0.2785.116 m), Microsoft Edge (25.10586.0.0) however does not work in Firefox (version 49.0.1). Is this likely due to the differences in date format?
The code below is my time-based score of a canvas game. The function obtains the date from the start of execution, and increases by 1 for each second.
It is key that the score starts from 0, increases by 1 per sec, and reaches 100 in the browser.
Looking for any solution that will make this work on Firefox - at the moment the 'score' appears static and does not count upwards, unlike Google Chrome and Edge.
Any ideas? - New to JS.
Thanks in advance for your help.
var start = new Date().getTime(),
score = '0.1';
var interval = window.setInterval(function() {
var time = new Date().getTime() - start;
score = Math.floor(time / 1000);
if(score === 100) {
window.clearInterval(interval);
if(!alert("You win!\nPress 'OK' to play again")){
window.location.reload();
}
}
document.getElementById('displayScore').innerHTML = score += '.00 Score';
});
<div id="displayScore"></div>
You need to pass the delay in your setIntetval because if you don't firefox assumes a default of 10 (millisec)
delay
The time, in milliseconds (thousandths of a second), the timer should delay in between executions of the specified function or code. If this parameter is less than 10, a value of 10 is used.
This makes it run every 10ms its a very low value so when you do the calculation like score = Math.floor(time / 1000); resulting value nears to zero and your var never increments
So I've got this JavaScript clock I'm working on and I want it to be perfectly synced with the clients' system clock. I know how to get the current time using a Date object and I know how to run the update function every 60000 milliseconds (1 minute). The thing is that the client might load the page when half a minute has already passed, making the clock lag behind with 30 seconds. Is there any way to just run the update function when the minute-variable actually changes? (I only want minute-precision.)
How I get the current time:
var time = new Date();
var currentHour = time.getHours();
var currentMinute = time.getMinutes();
How I run the update function every 60000 ms:
setInterval(update,60000); //"update" is the function that is run
When the user logs in, get the current time and seconds of the minute, subtract 60 to get the remaining seconds, then multiply to set the timer
var time = new Date(),
secondsRemaining = (60 - time.getSeconds()) * 1000;
setTimeout(function() {
setInterval(update, 60000);
}, secondsRemaining);
First, you have to understand that timers in javascript are not guaranteed to be called on time so therefore you cannot be perfectly synced at all times - javascript just isn't a real-time language like that. It is single threaded so a timer event has to wait for other javascript that might be executing at the time to finish before a timer can be executed. So, you must have a design that still does as best as possible even if the timer is delayed (called later than it's supposed to be).
If you wanted to try to stay as close to aligned and do the fewest screen updates and be the most friendly to mobile battery life, I'd suggest this self-aligning code which realigns itself on each tick based on the time remaining until the next minute change:
function runClock() {
var now = new Date();
var timeToNextTick = (60 - now.getSeconds()) * 1000 - now.getMilliseconds();
setTimeout(function() {
update();
runClock();
}, timeToNextTick);
}
// display the initial clock
update();
// start the running clock display that will update right on the minute change
runClock();
This has the advantage that it only calls the update once on the next minute boundary.
Working demo: http://jsfiddle.net/jfriend00/u7Hc5/
var time = new Date();
var currentHour = time.getHours();
var currentMinute = time.getMinutes();
var currentSecond = time.getSeconds();
var updateinterval = setInterval(startTimer,(60-currentSecond)*1000);
function startTimer(){
clearInterval(updateinterval);
setInterval(update,60000);
}
function update(){
var time = new Date();
console.log(time.getSeconds());
}
I would set an interval to run each second, then check if time.getSeconds() == 0. This way you could execute an action whenever a new minute starts, based on the client time.
I want to update a clock in the UI when the time changes from 12:01 to 12:02.
I can do a setInterval every 60 seconds, but the beginning might not be on the first second of a new minute. How can I ensure that it starts at the first second?
I think I need to find out how many seconds are left in the current minute and then do a setTimeout that fires setInterval when the seconds elapse.
var secondsLeft = ?; //calculate seconds left in this minute
setTimeout(function(){
setInterval(function(){
//update clock
}, 1000 * 60);
}, secondsLeft);
If moment.js makes it easier, that's fine with me.
Try this: secondsLeft = 60 - new Date().getSeconds()
I would store old value, use requestAnimationFrame to see if browser is ready to render and at the render check if the minute has changed from previous render.
I am developing a test engine web application. Users will be give some amount of time to answer questions. I want to create a countdown clock after which the test is finished. I'm using javascript right now but facing problems of refresh and back button in the browser.
Following is the javascript:
<script>
function countDown (count) {
if (count > 0) {
var hours = Math.floor(count/3600)
var minutes = Math.floor(count/60) - (hours*60)
var seconds = count - (minutes * 60) - (hours*3600)
var d = document.getElementById("countDiv");
d.innerHTML = hours + ":" + minutes + ":" + seconds;
else
document.location = "test_finished.html";
}
countDown(<%=#totaltime%>);
</script>
How can i disable the refresh and back button or some other workaround??
You cannot enforce such things using JavaScript.
One way would be to have records in the database which hold the test start date time in it, once a user starts a test the start time is set, upon loading the initial timer value is calculated using it, so you can have back and refresh working fine and the countdown timer always being accurate.