Is there any way to start a setInterval one second after another? - javascript

http://jsfiddle.net/9DP2d/
setInterval(toggleredBox, 1000);
setInterval(toggleorangeBox, 1000);
setInterval(toggleyellowBox, 1000);
var toggleredBox = function toggleredBox() {
$(".redBox").slideToggle(1000);
};
var toggleorangeBox = function toggleorangeBox() {
$(".orangeBox").slideToggle(1000);
};
var toggleyellowBox = function toggleyellowBox() {
$(".yellowBox").slideToggle(1000);
};
So the problem is that all 3 boxes are firing all at once: is there any way to get them to go one after another simultaneously?

Can do it like this:
setInterval(toggleredBox, 3000);
var toggleredBox = function toggleredBox() {
$(".redBox").slideToggle(1000);
setTimeout(toggleorangeBox, 1000);
};
var toggleorangeBox = function toggleorangeBox() {
$(".orangeBox").slideToggle(1000);
setTimeout(toggleyellowBox, 1000);
};
var toggleyellowBox = function toggleyellowBox() {
$(".yellowBox").slideToggle(1000);
};
Can also have another setTimeout in the last function and simply call the function where you want the animation to start.
fiddle

You can use setTimeout do delay the start:
setInterval(toggleredBox, 1000);
setTimeout(function(){
setInterval(toggleorangeBox, 1000);
}, 1000):
setTimeout(function(){
setInterval(toggleyellowBox, 1000);
}, 2000):
You can also use a single interval for all three, and use a counter to check when to toggle them the first time:
setInterval(toggleBoxes, 1000);
var cnt = 0;
function toggleBoxes() {
$(".redBox").slideToggle(1000);
if (cnt > 0) $(".orangeBox").slideToggle(1000);
if (cnt > 1) $(".yellowBox").slideToggle(1000);
cnt++;
};
Demo: http://jsfiddle.net/9DP2d/2/

To try to implement the "one after the other simultaneously" (whatever that means):
setInterval(toggleredBox, 1000);
var toggleredBox = function() {
$(".redBox").slideToggle(1000, toggleorangeBox);
};
var toggleorangeBox = function() {
$(".orangeBox").slideToggle(1000, toggleyellowBox);
};
var toggleyellowBox = function() {
$(".yellowBox").slideToggle(1000);
};

Related

Can't use variable as setInterval delay? [duplicate]

I have written a javascript function that uses setInterval to manipulate a string every tenth of a second for a certain number of iterations.
function timer() {
var section = document.getElementById('txt').value;
var len = section.length;
var rands = new Array();
for (i=0; i<len; i++) {
rands.push(Math.floor(Math.random()*len));
};
var counter = 0
var interval = setInterval(function() {
var letters = section.split('');
for (j=0; j < len; j++) {
if (counter < rands[j]) {
letters[j] = Math.floor(Math.random()*9);
};
};
document.getElementById('txt').value = letters.join('');
counter++
if (counter > rands.max()) {
clearInterval(interval);
}
}, 100);
};
Instead of having the interval set at a specific number, I would like to update it every time it runs, based on a counter. So instead of:
var interval = setInterval(function() { ... }, 100);
It would be something like:
var interval = setInterval(function() { ... }, 10*counter);
Unfortunately, that did not work. It seemed like "10*counter" equals 0.
So, how can I adjust the interval every time the anonymous function runs?
You could use an anonymous function:
var counter = 10;
var myFunction = function(){
clearInterval(interval);
counter *= 10;
interval = setInterval(myFunction, counter);
}
var interval = setInterval(myFunction, counter);
UPDATE: As suggested by A. Wolff, use setTimeout to avoid the need for clearInterval.
var counter = 10;
var myFunction = function() {
counter *= 10;
setTimeout(myFunction, counter);
}
setTimeout(myFunction, counter);
Use setTimeout() instead. The callback would then be responsible for firing the next timeout, at which point you can increase or otherwise manipulate the timing.
EDIT
Here's a generic function you can use to apply a "decelerating" timeout for ANY function call.
function setDeceleratingTimeout(callback, factor, times)
{
var internalCallback = function(tick, counter) {
return function() {
if (--tick >= 0) {
window.setTimeout(internalCallback, ++counter * factor);
callback();
}
}
}(times, 0);
window.setTimeout(internalCallback, factor);
};
// console.log() requires firebug
setDeceleratingTimeout(function(){ console.log('hi'); }, 10, 10);
setDeceleratingTimeout(function(){ console.log('bye'); }, 100, 10);
I like this question - inspired a little timer object in me:
window.setVariableInterval = function(callbackFunc, timing) {
var variableInterval = {
interval: timing,
callback: callbackFunc,
stopped: false,
runLoop: function() {
if (variableInterval.stopped) return;
var result = variableInterval.callback.call(variableInterval);
if (typeof result == 'number')
{
if (result === 0) return;
variableInterval.interval = result;
}
variableInterval.loop();
},
stop: function() {
this.stopped = true;
window.clearTimeout(this.timeout);
},
start: function() {
this.stopped = false;
return this.loop();
},
loop: function() {
this.timeout = window.setTimeout(this.runLoop, this.interval);
return this;
}
};
return variableInterval.start();
};
Example use
var vi = setVariableInterval(function() {
// this is the variableInterval - so we can change/get the interval here:
var interval = this.interval;
// print it for the hell of it
console.log(interval);
// we can stop ourselves.
if (interval>4000) this.stop();
// we could return a new interval after doing something
return interval + 100;
}, 100);
// we can change the interval down here too
setTimeout(function() {
vi.interval = 3500;
}, 1000);
// or tell it to start back up in a minute
setTimeout(function() {
vi.interval = 100;
vi.start();
}, 60000);
I had the same question as the original poster, did this as a solution. Not sure how efficient this is ....
let interval = 5000; // initial condition
let run = setInterval(request, interval); // start setInterval as "run"
function request() {
console.log(interval); // firebug or chrome log
clearInterval(run); // stop the setInterval()
// dynamically change the run interval
if (interval > 200) {
interval = interval * .8;
} else {
interval = interval * 1.2;
}
run = setInterval(request, interval); // start the setInterval()
}
This is my way of doing this, i use setTimeout:
var timer = {
running: false,
iv: 5000,
timeout: false,
cb : function(){},
start : function(cb,iv){
var elm = this;
clearInterval(this.timeout);
this.running = true;
if(cb) this.cb = cb;
if(iv) this.iv = iv;
this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv);
},
execute : function(e){
if(!e.running) return false;
e.cb();
e.start();
},
stop : function(){
this.running = false;
},
set_interval : function(iv){
clearInterval(this.timeout);
this.start(false, iv);
}
};
Usage:
timer.start(function(){
console.debug('go');
}, 2000);
timer.set_interval(500);
timer.stop();
A much simpler way would be to have an if statement in the refreshed function and a control to execute your command at regular time intervals . In the following example, I run an alert every 2 seconds and the interval (intrv) can be changed dynamically...
var i=1;
var intrv=2; // << control this variable
var refreshId = setInterval(function() {
if(!(i%intrv)) {
alert('run!');
}
i++;
}, 1000);
This can be initiated however you want. timeout is the method i used to keep it on the top of the hour.
I had the need for every hour to begin a code block on the hour. So this would start at server startup and run the interval hourly. Basicaly the initial run is to begin the interval within the same minute. So in a second from init, run immediately then on every 5 seconds.
var interval = 1000;
var timing =function(){
var timer = setInterval(function(){
console.log(interval);
if(interval == 1000){ /*interval you dont want anymore or increment/decrement */
interval = 3600000; /* Increment you do want for timer */
clearInterval(timer);
timing();
}
},interval);
}
timing();
Alternately if you wanted to just have something happen at start and then forever at a specific interval you could just call it at the same time as the setInterval. For example:
var this = function(){
//do
}
setInterval(function(){
this()
},3600000)
this()
Here we have this run the first time and then every hour.
I couldn't synchronize and change the speed my setIntervals too and I was about to post a question. But I think I've found a way. It should certainly be improved because I'm a beginner. So, I'd gladly read your comments/remarks about this.
<body onload="foo()">
<div id="count1">0</div>
<div id="count2">2nd counter is stopped</div>
<button onclick="speed0()">pause</button>
<button onclick="speedx(1)">normal speed</button>
<button onclick="speedx(2)">speed x2</button>
<button onclick="speedx(4)">speed x4</button>
<button onclick="startTimer2()">Start second timer</button>
</body>
<script>
var count1 = 0,
count2 = 0,
greenlight = new Boolean(0), //blocks 2nd counter
speed = 1000, //1second
countingSpeed;
function foo(){
countingSpeed = setInterval(function(){
counter1();
counter2();
},speed);
}
function counter1(){
count1++;
document.getElementById("count1").innerHTML=count1;
}
function counter2(){
if (greenlight != false) {
count2++;
document.getElementById("count2").innerHTML=count2;
}
}
function startTimer2(){
//while the button hasn't been clicked, greenlight boolean is false
//thus, the 2nd timer is blocked
greenlight = true;
counter2();
//counter2() is greenlighted
}
//these functions modify the speed of the counters
function speed0(){
clearInterval(countingSpeed);
}
function speedx(a){
clearInterval(countingSpeed);
speed=1000/a;
foo();
}
</script>
If you want the counters to begin to increase once the page is loaded, put counter1() and counter2() in foo() before countingSpeed is called. Otherwise, it takes speed milliseconds before execution.
EDIT : Shorter answer.
(function variableInterval() {
//whatever needs to be done
interval *= 2; //deal with your interval
setTimeout(variableInterval, interval);
//whatever needs to be done
})();
can't get any shorter
Here is yet another way to create a decelerating/accelerating interval timer. The interval gets multiplied by a factor until a total time is exceeded.
function setChangingInterval(callback, startInterval, factor, totalTime) {
let remainingTime = totalTime;
let interval = startInterval;
const internalTimer = () => {
remainingTime -= interval ;
interval *= factor;
if (remainingTime >= 0) {
setTimeout(internalTimer, interval);
callback();
}
};
internalTimer();
}
Make new function:
// set Time interval
$("3000,18000").Multitimeout();
jQuery.fn.extend({
Multitimeout: function () {
var res = this.selector.split(",");
$.each(res, function (index, val) { setTimeout(function () {
//...Call function
temp();
}, val); });
return true;
}
});
function temp()
{
alert();
}
This piece of code below accelerates (acceleration > 1) or decelerates (acceleration <1) a setInterval function :
function accelerate(yourfunction, timer, refresh, acceleration) {
var new_timer = timer / acceleration;
var refresh_init = refresh;//save this user defined value
if (refresh < new_timer ){//avoid reseting the interval before it has produced anything.
refresh = new_timer + 1 ;
};
var lastInter = setInterval(yourfunction, new_timer);
console.log("timer:", new_timer);
function stopLastInter() {
clearInterval(lastInter);
accelerate(yourfunction, new_timer, refresh_init, acceleration);
console.log("refresh:", refresh);
};
setTimeout(stopLastInter, refresh);
}
With :
timer: the setInterval initial value in ms (increasing or decreasing)
refresh: the time before a new value of timer is calculated. This is the step lenght
acceleration: the gap between the old and the next timer value. This is the step height
Inspired by the internal callback above, i made a function to fire a callback at fractions of minutes. If timeout is set to intervals like 6 000, 15 000, 30 000, 60 000 it will continuously adapt the intervals in sync to the exact transition to the next minute of your system clock.
//Interval timer to trigger on even minute intervals
function setIntervalSynced(callback, intervalMs) {
//Calculate time to next modulus timer event
var betterInterval = function () {
var d = new Date();
var millis = (d.getMinutes() * 60 + d.getSeconds()) * 1000 + d.getMilliseconds();
return intervalMs - millis % intervalMs;
};
//Internal callback
var internalCallback = function () {
return function () {
setTimeout(internalCallback, betterInterval());
callback();
}
}();
//Initial call to start internal callback
setTimeout(internalCallback, betterInterval());
};
This is my idea for times when you do not want loops like setInterval to overlap.
You also want to be able to set the loop execution delay and start and stop the loop, instansly on the fly.
I am using a loop_flag variable and a setTimeout function.
I set the main function to async so that you can call other functions in the body by calling await. When the main body of your code is running, the main loop waits and does not repeat itself. (which is not the case with setInterval)
An example of a simple code is:
//#NabiKAZ
document.getElementById("btn_start").addEventListener("click", function() {
console.log("Starting...");
loop_flag = true;
loop_func();
});
document.getElementById("btn_stop").addEventListener("click", function() {
console.log("Stoping...");
loop_flag = false;
});
var n = 0;
var loop_flag = false;
var loop_func = async function() {
if (!loop_flag) {
console.log("STOP.");
return;
}
//body main function inhere
n++;
console.log(n);
////
if (loop_flag) {
setTimeout(loop_func, document.getElementById("inp_delay").value);
} else {
console.log("STOP.");
}
}
<input id="inp_delay" value="1000">
<button id="btn_start">START</button>
<button id="btn_stop">STOP</button>
For a more complete code with a fetch request inside the loop, see here:
https://jsfiddle.net/NabiKAZ/a5hdw2bo/
You can use a variable and change the variable instead.
setInterval(() => function, variable)
You can do this by clearing the interval every iteration, changing the timer value and setting the interval again. Hope it helps ;)
For exemple:
const DOMCounter = document.querySelector(".counter")
let timer = 1000
const changeCounter = () => {
clearInterval(interval)
DOMCounter.innerHTML = timer
timer += 1000
timer == 5000 && timer == 1000
interval = setInterval(changeCounter, timer)
}
let interval = setInterval(changeCounter, timer)
<div class="container">
<p class="counter"></p>
</div>
var counter = 15;
var interval = function() {
setTimeout(function(){
// Write your code here and remove console.log, remember that you need declare yourDynamicValue and give it a value
console.log((new Date()).getTime())
window.counter = yourDynamicValue;
window.interval();
}, counter);
}
// It needs to run just once as init
interval();

Set up a counter for a JavaScript timer loop based on number of images

What I would like to do is set each BannerImg element to display: none one at a time using a timer setup. Then, once I have looped through all BannerImg elements, I want to reset them to display: block. It's basically like a image rotator that I'm trying to make...but right now, I'm not sure how to target each BannerImg element one at a time--I am targeting them all at once, which is not what I want to do.
jQuery.noConflict();
(function($) {
$(document).ready(function() {
var BannerCount = $('BannerImg').length;
var intervalID = window.setInterval(function() {
$('.BannerImg').toggleClass("HideBannerImg");
}, 2000);
});
}(jQuery));
Use .eq(index). You'll probably want to cache your collection to make it faster:
(function($) {
$(document).ready(function() {
var $banners = $('.BannerImg');
var index = 0;
var intervalID = window.setInterval(function() {
$banners.eq(index).toggleClass("HideBannerImg");
index++;
// Check to see if we've hit the end of the collection
// If so, stop the interval.
if (index === $banners.length) {
clearInterval(intervalID);
}
}, 2000);
});
}(jQuery));
I'm kind of guessing you want something like this (correct me if I'm wrong):
setInterval(function () {
if ($('.BannerImg').last().hasClass('HideBannerImg')) {
$('.HideBannerImg').first().removeClass('HideBannerImg');
} else {
$('.BannerImg').not('.HideBannerImg').first().addClass('HideBannerImg');
}
}, 1000);
jQuery.noConflict();
(function($) {
$(document).ready(function() {
var iterator = 0;
var BannerCount = $('BannerImg').length;
var intervalID = window.setInterval(function() {
$('.BannerImg').eq(iterator).toggleClass("HideBannerImg");
iterator += 1;
if (iterator === BannerCount.length - 1) {
clearInterval(intervalID);
$('.BannerImg').removeClass("HideBannerImg");
}
}, 2000);
});
}(jQuery));
try this recursive function
var images = $('.BannerImg').each();
var hideImage = function(index){
images[index].toggleClass("HideBannerImg");
if(index < images.length-1)
setTimeout(function(){
hideImage(index++);
}, 2000);
}
hideImage(0);
After calling $('.BannerImg') you need to use jQuery's each to loop over each of the elements it selected.
jQuery.noConflict();
(function($) {
$(document).ready(function() {
$('.BannerImg').each(function() {
var $this = $(this);
var intervalID = window.setInterval(function() {
$this.toggleClass("HideBannerImg");
}, 2000);
});
});
}(jQuery));
Just note that this will toggle on and off over and over until you clear the interval.

JavaScript - setInterval only running once [duplicate]

This question already has answers here:
Why does the setInterval callback execute only once?
(2 answers)
Closed 6 months ago.
http://jsfiddle.net/689nauny/
setInterval() is only running once... WTF is going on?
SO is asking for more details but providing a JSFiddle is about as descriptive as I can be? I've tried using an anonymous function and now a callback. I just don't get it? :-/
HTML
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<div id="qanda-timer-container">
<div class="qanda-timer">
<span id="qanda-time-remaining"></span>
</div>
</div>
JS
function intervalFunc(thinkingTime, answerTime)
{
jQuery('#qanda-time-remaining').text(''+(thinkingTime - 1));
}
function enableTimer(time)
{
var intervalID;
var hasThinkingTime = true;
var thinkingTime = time;
var hasAnswerTime = true;
var answerTime = 10;
if(hasThinkingTime && hasAnswerTime)
{
setInterval( intervalFunc(thinkingTime, answerTime), 1000);
}
setTimeout(function(){
clearInterval(intervalID);
}, time * 1000);
}
enableTimer(30);
You need to wrap the interval handler in a function:
intervalId = setInterval( function() { intervalFunc(thinkingTime, answerTime) }, 1000);
Your code as posted is calling the function and passing the result to setInterval(). The interval timer isn't running at all!
After you do that, you'll need to fix the problem of maintaining the descending time value. Currently you pass the variable as a parameter and subtract one from it, but you don't update the original variable.
function intervalFunc(thinkingTime, answerTime)
{
jQuery('#qanda-time-remaining').text(''+(thinkingTime));
}
Then change the setInterval setup:
intervalId = setInterval( function() { intervalFunc(--thinkingTime, answerTime) }, 1000);
}
Your code doesn't work because of this line:
setInterval( intervalFunc(thinkingTime, answerTime), 1000);
Change it into this:
setInterval( function(){
intervalFunc(thinkingTime, answerTime);
}, 1000);
You need to provide a function to setInterval(), while you are providing undefined.
This is why it doesn't run.
Running code:
function enableTimer(time)
{
var elem = jQuery('#qanda-time-remaining'), interval = setInterval( function(){
if(time/1 == time/1 && time) //if(!isNaN(time) && time>0)
{
elem.text( time-- );
}
else
{
clearInterval(interval);
elem.text(0);
}
}, 1000);
}
enableTimer(5);
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<div id="qanda-timer-container">
<div class="qanda-timer">
<span id="qanda-time-remaining"></span>
</div>
</div>
I have simplified your code to the extreme and is so much easy to read.
You can set a new parameter to which you provide a function that will run after the time is up:
function enableTimer(time, fn)
{
var elem = jQuery('#qanda-time-remaining'), interval = setInterval( function(){
if(time/1 == time/1 && time) //if(!isNaN(time) && time>0)
{
elem.text( time-- );
}
else
{
clearInterval(interval);
elem.text(0);
if( fn instanceof Function )//if fn is a function
{
fn();//call it
}
}
}, 1000);
}
enableTimer(5, function(){ alert('Time\'s up!'); });
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<div id="qanda-timer-container">
<div class="qanda-timer">
<span id="qanda-time-remaining"></span>
</div>
</div>
Here is a working example: http://jsfiddle.net/689nauny/3/
Your issue was partly with scope and in general how you decremented the count down variable
var thinkingTime = undefined;
var answerTime = undefined;
var intervalID = undefined;
function enableTimer(time) {
var hasThinkingTime = true;
thinkingTime = time;
var hasAnswerTime = true;
answerTime = 10;
if (hasThinkingTime && hasAnswerTime) {
intervalID = setInterval(function () {
thinkingTime -= 1;
jQuery('#qanda-time-remaining').text('' + (thinkingTime));
}, 1000);
}
setTimeout(function () {
clearInterval(intervalID);
}, time * 1000);
}
enableTimer(30);

JQuery Auto Click

I have a problem, I have 3 button lets say it's called #pos1, #pos2 and #pos3.
I want to makes it automatically click #pos1 button in 2 seconds, after that click the #pos2 after another 2 seconds, and #pos3 after another 2 seconds,
after that back to the #pos1 in another 2 seconds and so on via jQuery.
HTML
<button id="pos1">Pos1</button>
<button id="pos2">Pos2</button>
<button id="pos3">Pos3</button>
Anyone can help me please?
Try
$(function() {
var timeout;
var count = $('button[id^=pos]').length;
$('button[id^=pos]').click(function() {
var $this = $(this);
var id = $this.attr('id');
var next = parseInt(id.substring(4), 10) + 1;
if( next >= count ){
next = 1
}
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
$('#pos' + next).trigger('click');
}, 2000);
})
timeout = setTimeout(function() {
$('#pos1').trigger('click');
}, 2000);
})
var posArray = ["#pos1", "#pos2", "#pos3"];
var counter = 0;
setInterval(function() {
$(posArray[counter]).triggerHandler('click');
counter = ((counter<2) ? counter+1 : 0);
}, 2000);
That should do the trick, though you did not mention when you want it to stop running.
Well I don't know what you already have but technically it could be done via triggerHandler()
var currentPos = 1,
posCount = 3;
autoclick = function() {
$('#pos'+currentPos).triggerHandler('click');
currentPos++;
if(currentPos > posCount) { currentPos = 1; }
};
window.setInterval(autoclick,2000);
If I have understood you question right, you need to perform click in a continuous loop in the order pos1>pos2>pos3>pos1>pos2 and so on. If this is what you want, you can use jQuery window.setTimeout for this. Code will be something like this:
window.setTimeout(performClick, 2000);
var nextClick = 1;
function performClick() {
if(nextClick == 1)
{
$("#pos1").trigger("click");
nextClick = 2;
}
else if(nextClick==2)
{
$("#pos2").trigger("click");
nextClick = 3;
}
else if(nextClick == 3)
{
$("#pos3").trigger("click");
nextClick = 1;
}
window.setTimeout(performClick, 2000);
}
This is quite buggy but will solve your problem.
using setInterval()
Calls a function or executes a code snippet repeatedly, with a fixed time delay between each call to that function.
var tempArray = ["pos1", "pos2", "pos3"]; //create an array to loop through
var arrayCounter = 0;
setInterval(function() {
$('#' + tempArray[arrayCounter ]).trigger('click');
arrayCounter = arrayCounter <2 ? arrayCounter +1 : 0;
}, 2000);
fiddle here
check your console for fiddle example

Changing the interval of SetInterval while it's running

I have written a javascript function that uses setInterval to manipulate a string every tenth of a second for a certain number of iterations.
function timer() {
var section = document.getElementById('txt').value;
var len = section.length;
var rands = new Array();
for (i=0; i<len; i++) {
rands.push(Math.floor(Math.random()*len));
};
var counter = 0
var interval = setInterval(function() {
var letters = section.split('');
for (j=0; j < len; j++) {
if (counter < rands[j]) {
letters[j] = Math.floor(Math.random()*9);
};
};
document.getElementById('txt').value = letters.join('');
counter++
if (counter > rands.max()) {
clearInterval(interval);
}
}, 100);
};
Instead of having the interval set at a specific number, I would like to update it every time it runs, based on a counter. So instead of:
var interval = setInterval(function() { ... }, 100);
It would be something like:
var interval = setInterval(function() { ... }, 10*counter);
Unfortunately, that did not work. It seemed like "10*counter" equals 0.
So, how can I adjust the interval every time the anonymous function runs?
You could use an anonymous function:
var counter = 10;
var myFunction = function(){
clearInterval(interval);
counter *= 10;
interval = setInterval(myFunction, counter);
}
var interval = setInterval(myFunction, counter);
UPDATE: As suggested by A. Wolff, use setTimeout to avoid the need for clearInterval.
var counter = 10;
var myFunction = function() {
counter *= 10;
setTimeout(myFunction, counter);
}
setTimeout(myFunction, counter);
Use setTimeout() instead. The callback would then be responsible for firing the next timeout, at which point you can increase or otherwise manipulate the timing.
EDIT
Here's a generic function you can use to apply a "decelerating" timeout for ANY function call.
function setDeceleratingTimeout(callback, factor, times)
{
var internalCallback = function(tick, counter) {
return function() {
if (--tick >= 0) {
window.setTimeout(internalCallback, ++counter * factor);
callback();
}
}
}(times, 0);
window.setTimeout(internalCallback, factor);
};
// console.log() requires firebug
setDeceleratingTimeout(function(){ console.log('hi'); }, 10, 10);
setDeceleratingTimeout(function(){ console.log('bye'); }, 100, 10);
I like this question - inspired a little timer object in me:
window.setVariableInterval = function(callbackFunc, timing) {
var variableInterval = {
interval: timing,
callback: callbackFunc,
stopped: false,
runLoop: function() {
if (variableInterval.stopped) return;
var result = variableInterval.callback.call(variableInterval);
if (typeof result == 'number')
{
if (result === 0) return;
variableInterval.interval = result;
}
variableInterval.loop();
},
stop: function() {
this.stopped = true;
window.clearTimeout(this.timeout);
},
start: function() {
this.stopped = false;
return this.loop();
},
loop: function() {
this.timeout = window.setTimeout(this.runLoop, this.interval);
return this;
}
};
return variableInterval.start();
};
Example use
var vi = setVariableInterval(function() {
// this is the variableInterval - so we can change/get the interval here:
var interval = this.interval;
// print it for the hell of it
console.log(interval);
// we can stop ourselves.
if (interval>4000) this.stop();
// we could return a new interval after doing something
return interval + 100;
}, 100);
// we can change the interval down here too
setTimeout(function() {
vi.interval = 3500;
}, 1000);
// or tell it to start back up in a minute
setTimeout(function() {
vi.interval = 100;
vi.start();
}, 60000);
I had the same question as the original poster, did this as a solution. Not sure how efficient this is ....
let interval = 5000; // initial condition
let run = setInterval(request, interval); // start setInterval as "run"
function request() {
console.log(interval); // firebug or chrome log
clearInterval(run); // stop the setInterval()
// dynamically change the run interval
if (interval > 200) {
interval = interval * .8;
} else {
interval = interval * 1.2;
}
run = setInterval(request, interval); // start the setInterval()
}
This is my way of doing this, i use setTimeout:
var timer = {
running: false,
iv: 5000,
timeout: false,
cb : function(){},
start : function(cb,iv){
var elm = this;
clearInterval(this.timeout);
this.running = true;
if(cb) this.cb = cb;
if(iv) this.iv = iv;
this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv);
},
execute : function(e){
if(!e.running) return false;
e.cb();
e.start();
},
stop : function(){
this.running = false;
},
set_interval : function(iv){
clearInterval(this.timeout);
this.start(false, iv);
}
};
Usage:
timer.start(function(){
console.debug('go');
}, 2000);
timer.set_interval(500);
timer.stop();
A much simpler way would be to have an if statement in the refreshed function and a control to execute your command at regular time intervals . In the following example, I run an alert every 2 seconds and the interval (intrv) can be changed dynamically...
var i=1;
var intrv=2; // << control this variable
var refreshId = setInterval(function() {
if(!(i%intrv)) {
alert('run!');
}
i++;
}, 1000);
This can be initiated however you want. timeout is the method i used to keep it on the top of the hour.
I had the need for every hour to begin a code block on the hour. So this would start at server startup and run the interval hourly. Basicaly the initial run is to begin the interval within the same minute. So in a second from init, run immediately then on every 5 seconds.
var interval = 1000;
var timing =function(){
var timer = setInterval(function(){
console.log(interval);
if(interval == 1000){ /*interval you dont want anymore or increment/decrement */
interval = 3600000; /* Increment you do want for timer */
clearInterval(timer);
timing();
}
},interval);
}
timing();
Alternately if you wanted to just have something happen at start and then forever at a specific interval you could just call it at the same time as the setInterval. For example:
var this = function(){
//do
}
setInterval(function(){
this()
},3600000)
this()
Here we have this run the first time and then every hour.
I couldn't synchronize and change the speed my setIntervals too and I was about to post a question. But I think I've found a way. It should certainly be improved because I'm a beginner. So, I'd gladly read your comments/remarks about this.
<body onload="foo()">
<div id="count1">0</div>
<div id="count2">2nd counter is stopped</div>
<button onclick="speed0()">pause</button>
<button onclick="speedx(1)">normal speed</button>
<button onclick="speedx(2)">speed x2</button>
<button onclick="speedx(4)">speed x4</button>
<button onclick="startTimer2()">Start second timer</button>
</body>
<script>
var count1 = 0,
count2 = 0,
greenlight = new Boolean(0), //blocks 2nd counter
speed = 1000, //1second
countingSpeed;
function foo(){
countingSpeed = setInterval(function(){
counter1();
counter2();
},speed);
}
function counter1(){
count1++;
document.getElementById("count1").innerHTML=count1;
}
function counter2(){
if (greenlight != false) {
count2++;
document.getElementById("count2").innerHTML=count2;
}
}
function startTimer2(){
//while the button hasn't been clicked, greenlight boolean is false
//thus, the 2nd timer is blocked
greenlight = true;
counter2();
//counter2() is greenlighted
}
//these functions modify the speed of the counters
function speed0(){
clearInterval(countingSpeed);
}
function speedx(a){
clearInterval(countingSpeed);
speed=1000/a;
foo();
}
</script>
If you want the counters to begin to increase once the page is loaded, put counter1() and counter2() in foo() before countingSpeed is called. Otherwise, it takes speed milliseconds before execution.
EDIT : Shorter answer.
(function variableInterval() {
//whatever needs to be done
interval *= 2; //deal with your interval
setTimeout(variableInterval, interval);
//whatever needs to be done
})();
can't get any shorter
Here is yet another way to create a decelerating/accelerating interval timer. The interval gets multiplied by a factor until a total time is exceeded.
function setChangingInterval(callback, startInterval, factor, totalTime) {
let remainingTime = totalTime;
let interval = startInterval;
const internalTimer = () => {
remainingTime -= interval ;
interval *= factor;
if (remainingTime >= 0) {
setTimeout(internalTimer, interval);
callback();
}
};
internalTimer();
}
Make new function:
// set Time interval
$("3000,18000").Multitimeout();
jQuery.fn.extend({
Multitimeout: function () {
var res = this.selector.split(",");
$.each(res, function (index, val) { setTimeout(function () {
//...Call function
temp();
}, val); });
return true;
}
});
function temp()
{
alert();
}
This piece of code below accelerates (acceleration > 1) or decelerates (acceleration <1) a setInterval function :
function accelerate(yourfunction, timer, refresh, acceleration) {
var new_timer = timer / acceleration;
var refresh_init = refresh;//save this user defined value
if (refresh < new_timer ){//avoid reseting the interval before it has produced anything.
refresh = new_timer + 1 ;
};
var lastInter = setInterval(yourfunction, new_timer);
console.log("timer:", new_timer);
function stopLastInter() {
clearInterval(lastInter);
accelerate(yourfunction, new_timer, refresh_init, acceleration);
console.log("refresh:", refresh);
};
setTimeout(stopLastInter, refresh);
}
With :
timer: the setInterval initial value in ms (increasing or decreasing)
refresh: the time before a new value of timer is calculated. This is the step lenght
acceleration: the gap between the old and the next timer value. This is the step height
Inspired by the internal callback above, i made a function to fire a callback at fractions of minutes. If timeout is set to intervals like 6 000, 15 000, 30 000, 60 000 it will continuously adapt the intervals in sync to the exact transition to the next minute of your system clock.
//Interval timer to trigger on even minute intervals
function setIntervalSynced(callback, intervalMs) {
//Calculate time to next modulus timer event
var betterInterval = function () {
var d = new Date();
var millis = (d.getMinutes() * 60 + d.getSeconds()) * 1000 + d.getMilliseconds();
return intervalMs - millis % intervalMs;
};
//Internal callback
var internalCallback = function () {
return function () {
setTimeout(internalCallback, betterInterval());
callback();
}
}();
//Initial call to start internal callback
setTimeout(internalCallback, betterInterval());
};
This is my idea for times when you do not want loops like setInterval to overlap.
You also want to be able to set the loop execution delay and start and stop the loop, instansly on the fly.
I am using a loop_flag variable and a setTimeout function.
I set the main function to async so that you can call other functions in the body by calling await. When the main body of your code is running, the main loop waits and does not repeat itself. (which is not the case with setInterval)
An example of a simple code is:
//#NabiKAZ
document.getElementById("btn_start").addEventListener("click", function() {
console.log("Starting...");
loop_flag = true;
loop_func();
});
document.getElementById("btn_stop").addEventListener("click", function() {
console.log("Stoping...");
loop_flag = false;
});
var n = 0;
var loop_flag = false;
var loop_func = async function() {
if (!loop_flag) {
console.log("STOP.");
return;
}
//body main function inhere
n++;
console.log(n);
////
if (loop_flag) {
setTimeout(loop_func, document.getElementById("inp_delay").value);
} else {
console.log("STOP.");
}
}
<input id="inp_delay" value="1000">
<button id="btn_start">START</button>
<button id="btn_stop">STOP</button>
For a more complete code with a fetch request inside the loop, see here:
https://jsfiddle.net/NabiKAZ/a5hdw2bo/
You can use a variable and change the variable instead.
setInterval(() => function, variable)
You can do this by clearing the interval every iteration, changing the timer value and setting the interval again. Hope it helps ;)
For exemple:
const DOMCounter = document.querySelector(".counter")
let timer = 1000
const changeCounter = () => {
clearInterval(interval)
DOMCounter.innerHTML = timer
timer += 1000
timer == 5000 && timer == 1000
interval = setInterval(changeCounter, timer)
}
let interval = setInterval(changeCounter, timer)
<div class="container">
<p class="counter"></p>
</div>
var counter = 15;
var interval = function() {
setTimeout(function(){
// Write your code here and remove console.log, remember that you need declare yourDynamicValue and give it a value
console.log((new Date()).getTime())
window.counter = yourDynamicValue;
window.interval();
}, counter);
}
// It needs to run just once as init
interval();

Categories

Resources