I have a simple javascript function that loads on document ready:
var start = 1;
var speed = 1000;
$(document).ready(function () {
go();
setInterval(function () {
go();
}, speed);
This is the function in details:
function go() {
$("#score").html(start.toLocaleString());
start += 1;
}
This is basically a counter which starts from number 1 to infinite, at 1000 milliseconds speed. Here is the thing , now: I have another function:
function modify() {
speed = 500;
}
which regulates the setIntval speed on the main function. The problem is it applies on page refresh only. How do I update it in real time without refreshing page?
You can't update the current one, you have to stop it and set a new timer, which does the same but with a different delay.
var speed = 1000;
var start = 1;
function go() {
$("#score").html(start.toLocaleString());
start += 1;
}
function startGoTimer(){
return = setInterval(function () {
go();
}, speed);
}
function modifyTimer( previousTimer, newDelay=500) {
clearInterval(previousTimer);
speed = newDelay;
startGoTimer();
}
var timer = startGoTimer();
// Some code
modifyTimer(timer, 500);
For fun I just tested what would hapopen if you just change the time:
var timing = 1000;
var interval = setInterval(function(){console.log("test")}, timing);
// Now we get a log every 1000ms, change the var after some time (via console):
timing = 10;
// still an interval of 1000ms.
A really simple solution is to make use of the setInterval's parameters,
var intervalID = scope.setInterval(func, delay[, param1, param2, ...]);
and also pass the speed as param1.
Then, at each interval, check if it changed, and if, clear the existing timer and fire up a new.
Stack snippet
var start = 1;
var speed = 1000;
var timer;
$(document).ready(function() {
go();
timer = setInterval(function(p) {
go(p);
}, speed, speed);
// for this demo
$("button").click(function(){ speed = speed/2});
})
function go(p) {
if(p && p != speed) {
clearInterval(timer);
timer = setInterval(function(p) {
go(p);
}, speed, speed);
}
$("#score").html(start.toLocaleString());
start += 1;
}
div {
display: inline-block;
width: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="score">0</div>
<button>Modify</button>
Related
I have the following countdown function in javascript:
countdownTimer() {
// exit method if it is active
if(this.isCountdownActive == true){
return;
}
// first time set true
this.isCountdownActive = true
this.countdown = 10
// Define the work to be done
var doWork = () => {
if(this.countdown <= 0) {
ticker.stop();
this.countdown = 10
this.isCountdownActive = false
if (this.thisUser.captain) {
Store.submitTurnEnd();
}
}
this.countdown -= 1;
};
// Define what to do if something goes wrong
var doError = function() {
console.warn('The drift exceeded the interval.');
};
// (The third argument is optional)
var ticker = new Util.AdjustingInterval(doWork, 1000, doError);
ticker.start()
},
Here is the adjusting interval function
function AdjustingInterval(workFunc, interval, errorFunc) {
var that = this;
var expected, timeout;
this.interval = interval;
this.start = function() {
expected = Date.now() + this.interval;
timeout = setTimeout(step, this.interval);
}
this.stop = function() {
clearTimeout(timeout);
}
function step() {
var drift = Date.now() - expected;
if (drift > that.interval) {
// You could have some default stuff here too...
if (errorFunc) errorFunc();
}
workFunc();
expected += that.interval;
timeout = setTimeout(step, Math.max(0, that.interval-drift));
}
}
I believe this should work, however the timer still runs too fast occasionally and doesn't reset correctly. I would say 75% of the time it works fine, but after I click it gets "jumpy" and goes too fast. Also, the timer doesn't stop correctly. So that it cycles continuously.
Thanks for the help.
Just adjust the ms to however precise you want
const span = document.getElementById("t");
let d = new Date();
d.setHours(d.getHours()+1); // demo time
let tId = setInterval(() => span.innerText = new Date(d.getTime()-new Date().getTime()).toLocaleTimeString(),100)
<span id="t"></span>
I am working on knockout js.
In that i have a recursive function which executes a function every minute. for that am using a timer every 60 sec it will execute also same will be reflecting in the UI also.
In my case, if i try to assign or initialize a timer value(observable) which is inside a loop, it doesn't reflecting instead of reflecting it is added to the pipeline and that much time loop is running simultaneously.
In that case i want to kill the loop and again want to restart every time i am changing the timer value.
timerInSec=60;
var loop = function () {
if (this.timer() < 1) {
myFunction()
this.timer(this.timerInSec - 1);
setTimeout(loop, 1000);
} else {
this.timer(this.timer() - 1);
setTimeout(loop, 1000);
}
};
loop();
Here is my solution. Please check.
timerInSec = 60;
const Loop = (function () {
let timer = 0;
let timerId = -1;
const myFunction = function () {
console.log('finished');
}
const fnLog = function (tm) {
console.log('current time = ', tm);
}
const fnProc = function () {
timerId = setTimeout(myFunction, 1000 * timer);
}
return {
start: function (tm = 60) {
this.stop();
timer = tm;
fnProc();
},
stop: function () {
if (timerId !== -1) {
clearTimeout(timerId);
timerId = -1;
}
}
}
})();
Loop.start(timerInSec);
setTimeout(() => {
Loop.start(timerInSec);
}, 500);
I'm trying to create a simple countdown timer. It counts down from the number entered.
However, I'm trying to clear the interval when the counter gets to 0. At the moment it seems to acknowledge the if statement, but not clearInterval().
http://jsfiddle.net/tmyie/cf3Hd/
$('.click').click(function () {
$('input').empty();
var rawAmount = $('input').val();
var cleanAmount = parseInt(rawAmount) + 1;
var timer = function () {
cleanAmount--;
if (cleanAmount == 0) {
clearInterval(timer);
}
$('p').text(cleanAmount);
};
setInterval(timer, 500);
})
You're not saving the return value of the call to setInterval, which is the value that needs to be passed to clearInterval. Passing the timer handler does no good.
var timer, timerHandler = function () {
cleanAmount--;
if (cleanAmount == 0) {
clearInterval(timer);
}
$('p').text(cleanAmount);
};
timer = setInterval(timerHandler, 500);
I need my code to run x amount of times and then pause for 30 seconds or so before resuming. Any ideas?
myslidefunction();
var tid = setInterval(myslidefunction, 1000);
function myslidefunction() {
setTimeout(function () {
//do stuff
}, 400);
};
You can keep a run-count, and use normal_duration + 30000 as the setTimeout delay for the X+ 1st time.
var runCount = 0, runsBeforeDelay = 20;
function myslidefunction(){
// .. stuff
runCount++;
var delay = 0;
if(runCount > runsBeforeDelay) {
runCount = 0;
delay = 30000;
}
setTimeout(myslidefunction, 400 + delay);
};
// start it off
setTimeout(myslidefunction, 1000);
var counter = 0;
var mySlideFunction = function(){
/* your "do stuff" code here */
counter++;
if(counter>=10){
counter = 0;
setTimeout(mySlideFunction, 30000);
}else{
setTimeout(mySlideFunction, 1000);
}
}
mySlideFunction();
(function() {
var count = {
digit: 0,
increment: function() {
var interval = setInterval(function() {
if (++count.digit == 10) {
clearInterval(interval);
count.decrement();
}
var update = document.getElementById("liveUpdate");
update.innerHTML = count.digit;
}, 500);
},
decrement: function() {
var interval = setInterval(function() {
if (--count.digit == -1) {
clearInterval(interval);
}
}, 500);
}
};
count.increment();
})();
It stops but it doesn't go down? What could be the problem?
Your decrement function never updates the output anywhere. The variable is going down but you don't show that on screen.
Try (or check the corresponding JSFiddle):
(function() {
var update = document.getElementById("liveUpdate");
var count = {
digit: 0,
increment: function() {
var interval = setInterval(function() {
if (++count.digit == 10) {
clearInterval(interval);
count.decrement();
}
update.innerHTML = count.digit;
}, 500);
},
decrement: function() {
var interval = setInterval(function() {
if (--count.digit == -1) {
clearInterval(interval);
}
update.innerHTML = count.digit;
}, 500);
}
};
count.increment();
})();
setInterval will call the function every 500 seconds. It will not stop until you stop it. You can read more about stopping it at Stop setInterval call in JavaScript
It't not a bug, it's a feature ;-). setInterval() runs the given function in a loop with a given interval (500 ms). See this article for details.