I'm trying to disable 2 functions when a certain time period is reached and enable the other 2 after that time period. So the second 2 functions would have to be disabled to begin with.
I was thinking of using the following code to wrap around the functions:
Code:
var startTime = new Date().getTime();
var interval = setInterval(function(){
if(new Date().getTime() - startTime > 5000){
clearInterval(interval);
return;
}
function 1() {}
$(function 2() {});
}, 1000);
function 3() {}
$(function 4() {});
Can you help?
If you want to control whether functions do something or not, based on how much time has elapsed, it would probably be easier to set a flag after the interval you need, and then have your functions check that flag to decide if they are going to do something:
var timedOut = false;
setTimeout(function () {
timedOut = true;
}, 5000);
function one() {
if (!timedOut) {
// do something
}
}
function two() {
if (!timedOut) {
// do something
}
}
function three() {
if (timedOut) {
// do something
}
}
function four() {
if (timedOut) {
// do something
}
}
This should get you started; I've simply redefined the original func1/func2 functions after a set time (5 seconds, as your example uses). This could do any number of things (such as remove the function definition altogether).
(function(document,window,undefined){
// Used simply to show output to the window.
var db = document.getElementById('db');
// Here we define the initial state of our two functions.
// Nothing magical here, just outputting a description.
window.func1 = function(){
db.innerHTML += 'Hello from original func1\r\n';
}
window.func2 = function(){
db.innerHTML += 'Hello from original func2\r\n';
}
// Here we keep the same format you used (using the Date to
// define when one's been deprecated over the other).
var startTime = new Date().getTime(),
interval = setInterval(function(){
var currentTime = new Date().getTime(),
delta = currentTime - startTime;
if (delta > 5000){
// In here, now that the specified amount of time has
// elapsed, we redefine the meaning of the two original
// functions. We could also simply remove them.
window.func1 = function(){
db.innerHTML += 'Hello from NEW func1\r\n';
}
window.func2 = function(){
db.innerHTML += 'Hello from NEW func2\r\n';
}
clearInterval(interval);
}
}, 1000);
})(document,window);
// This is here just to show you how one definition is changed
// in place of another.
setInterval(function(){
func1();
func2();
}, 1000);
<pre id="db"></pre>
If you mean 'disabling' the functions after certain amount of seconds then this should do the trick.
var secondsLimit = 10,
a = 0,
b = setInterval(function () { a += 1; }, 1000 });
function A() {
if (a > secondsLimit) {
return;
}
// do stuff
}
You can change the functions if you call them e.g. by a global variable scope.
In the following example based on your code, the functions switch after 4 seconds.
var function1 = function() {
console.log("function 1 active");
};
var function2 = function() {
console.log("function 2 active")
}
var startTime = new Date().getTime();
setTimeout(function() {
function1 = function() {
console.log("now function 3 is active instead of function 1");
}
function2 = function() {
console.log("now function 4 is active instead of function 2");
}
}, 4000);
//the following code is just for testing reasons
var interval = setInterval(function() {
function1();
function2();
}, 1000)
Related
I am using the below functions to start and stop spin.Basically I am trying to add an Autospin button and tried below approach but its not working.Start function is working but stop not working.
var nIntervId;
this._onAutoSpin = function(){
s_oGame.onSpin();
nIntervId = setInterval(this._onAutoSpin, 10 * 1000);
};
this._offAutoSpin = function(){
clearInterval(nIntervId);
};
The issue is because you're recursively starting a new interval every time it fires, therefore you only stop the latest timer, not the previous.
To fix this change your logic so that there is no possible recursion and there is only ever one interval running:
function Foo() {
var nIntervId;
this._onAutoSpin = function() {
nIntervId = setInterval(this._doAutoSpin, 1 * 1000); // modified for demo
}
this._doAutoSpin = function() {
console.log('spinning...');
};
this._offAutoSpin = function() {
console.log('stopped');
clearInterval(nIntervId);
};
}
var foo = new Foo();
foo._onAutoSpin();
setTimeout(foo._offAutoSpin, 5000); // stop after 5 seconds
If you want to do this recursively then you need to use setTimeout(). You also need to cache the this reference so that it is maintained within the successive calls:
function Foo() {
var nIntervId;
this._onAutoSpin = function() {
var _this = this;
console.log('spinning...');
nIntervId = setTimeout(function() {
_this._onAutoSpin();
}, 1 * 1000); // modified for demo
}
this._offAutoSpin = function() {
console.log('stopped');
clearInterval(nIntervId);
};
}
var foo = new Foo();
foo._onAutoSpin();
setTimeout(foo._offAutoSpin, 5000); // stop after 5 seconds
try to use setTimeout instead of setInterval because setInterval creates a new timer every time without destroying the last one.
var nIntervId;
this._onAutoSpin = function(){
s_oGame.onSpin();
nIntervId = setTimeout(this._onAutoSpin, 10 * 1000);
};
this._offAutoSpin = function(){
clearTimeout(nIntervId);
};
I have a setInterval loop. It's set to 3500 milliseconds, like so:-
var loop = setInterval(function() { /*stuff*/ }, 3500);
At one point in 'stuff' if a certain situation occurs, I want to force a new iteration of the loop and NOT WAIT for the 3500 milliseconds. How is that possible? Is it continue or do I just need to frame the process differently?
You could try writing an anonymous self-calling function using setTimeout instead of setInterval:
var i = 0;
(function() {
// stuff
i++;
if (i % 2 == 0) {
// If some condition occurs inside the function, then call itself once again
// immediately
arguments.callee();
} else {
// otherwise call itself in 3 and a half seconds
window.setTimeout(arguments.callee, 3500);
}
})(); // <-- call-itself immediately to start the iteration
UPDATE:
Due to a disagreement expressed in the comments section against the usage of arguments.callee, here's how the same could be achieved using a named function:
var i = 0;
var doStuff = function() {
// stuff
i++;
if (i % 2 == 0) {
// If some condition occurs inside the function, then call itself once again
// immediately
doStuff();
} else {
// otherwise call itself in 3 and a half seconds
window.setTimeout(doStuff, 3500);
}
};
doStuff();
You can use something like this... using setTimeout instead of setInterval...
<script type="text/javascript">
var show;
var done = false;
show = setTimeout(showHideForm, 3500);
function showHideForm() {
// Do something
if(done) {
clearTimeout(show);
show = setTimeout(showHideForm, 2000);
}
}
</script>
clearTimeout takes as argument the handle which is returned by setTimeout.
Use a named function and call it when you want.
var loop = setInterval(loopFunc, 3500);
function loopFunc(){
//do something
}
function anticipate(){
clearInterval(loop); //Stop interval
loopFunc(); //Call your function
loop = setInterval(loopFunc, 3500); //Reset the interval if you want
}
My contrived example:
var time = 3500,
loops = 0,
loop;
(function run(){
var wait = time,
dontwait = false;
if (loops++ == 5) {
loops = 0;
dontwait = 1000;
}
console.log('Interval: ', dontwait || wait);
return loop = setTimeout(run, dontwait || wait);
})();
http://jsfiddle.net/NX43d/1/
Basically, a self-invoking function looping back on a self-calling function, with (!) shorthand variable switching. Nifty.
function looper(t) {
var loop = setInterval(function() {
document.write(s++);
if (mycondition) { // here is your condition
loopagain(200); // specify the time which new loop will do
loop = window.clearInterval(loop); // clear the first interval
return; // exit from this function!
}
}, t);
}
window.onload = looper(1000); // this will have default setInterval function time ans will start at window load!
function loopagain(t) {
looper(t);
}
http://jsfiddle.net/tFCZP/
Ok, really simple question. I'm taking a crash course in javascript.
If I use
timer = setTimeout(..., 500) to set a timer, and then clearTimeout(timer) to clear the timer, the integer value of timer doesn't change, so my question is how to know if a timer is timed out or cleared?
I want to use if (timer) {...} , but obviously a positive integer always returns true.
If you're looking for something more formal, you could build javascript class that encapsulates the setTimeout/clearTimeout functionality.
Such a class might look something like this:
/** class Timer **/
var Timer = function(delayMs, callbackFunc) {
this.delayMs = delayMs;
this.callbackFunc = callbackFunc;
this.timerState = 'new';
}
Timer.prototype.start = function() {
if( this.tmr ) return;
var self = this;
this.timerState = 'running';
this.tmr = setTimeout(function() { self._handleTmr(); }, this.delayMs);
}
Timer.prototype.cancel = function() {
if( ! this.tmr ) return;
clearTimeout(this.tmr);
this.tmr = null;
this.timerState = 'canceled';
}
Timer.prototype._handleTmr = function() {
this.tmr = null;
this.timerState = 'completed';
this.callbackFunc();
}
I've also included a timerState attribute that would let you easily determine whether the timer was "completed" or "canceled".
You would use it like this:
var t = new Timer(500, function() {
alert('timer completed');
});
t.start();
// do whatever...
// now cancel the timer if it hasn't completed yet.
t.cancel();
// maybe you do some other stuff...
// then check the timerState, and act accordingly.
//
if( t.timerState == 'canceled' ) {
alert("the timer was canceled!");
} else {
alert("the timer completed uneventfully.");
}
You can extend the same basic idea to include additional functionality if you need it (eg. repeating timer, start/stop/resume, etc.)
assign null to the timer after the clearTimeout(timer)
If you clear the timeout the callback won't be executed. So if the callback is executed it means that 500ms have passed since you've set the timeout.
For example:
var timer = setTimeout(function() {
alert('you will never see this alert');
}, 500);
clearTimeout(timer);
Here is something that I use for timer events! Hope this helps.
var toggleTimeOut = (function () {
var _timeout;
return function (clear_timeout) {
if(!clear_timeout)
{
_timeout = setTimeout( function () {/*DO YOUR STUFF*/}, 5000);
}
else
{
if(typeof _timeout != typeof undefined && _timeout != 0)
{
clearTimeout(_timeout);
_timeout= 0;
}
}
}
})();
I avoid using flags in JS in general but this is a case where it makes sense and keeps things nice and simple. The idea is you set a flag once your timer has fired and then you can examine that elsewhere in code.
let fired = false;
// Set your timeout to do future work...
const timeout = window.setTimeout(() => {
fired = true;
// ...
}, 3000);
// Test it
const testInterval = window.setInterval(() => {
console.log(`Timer has ${fired ? ' ' : 'not '}fired`);
fired && window.clearInterval(testInterval);
}, 500);
Greetings,
I have the following JS code:
var reloadTimer = function (options) {
var seconds = options.seconds || 0,
logoutURL = options.logoutURL,
message = options.message;
this.start = function () {
setTimeout(function (){
if ( confirm(message) ) {
// RESET TIMER HERE
$.get("renewSession.php");
} else {
window.location.href = logoutURL;
}
}, seconds * 1000);
}
return this;
};
And I would like to have the timer reset where I have the comment for RESET TIMER HERE. I have tried a few different things to no avail. Also the code calling this block is the following:
var timer = reloadTimer({ seconds:20, logoutURL: 'logout.php',
message:'Do you want to stay logged in?'});
timer.start();
The code may look familiar as I found it on SO :-)
Thanks!
First of all, you need to use the new operator in var timer = new reloadTimer, and also reloadTimer should be capitalized into ReloadTimer to signify that it needs to be used with new.
The reason why you need new is because the function references this and when used without new this will be the global scope instead of the instance it self.
To reset a timer you just call window.clearTimeout with the timers reference as the parameter
var timer = window.setTimeout(....
...
window.clearTimeout(timer);
UPDATE
By RESET do you actally mean to restart the timer?
If so, just use setInterval instead of setTimeout
UPDATE 2
And here is a slightly better approach (if you still want to use such a class to encapsulate something so trivial)
var ReloadTimer = function(options){
var seconds = options.seconds || 0, logoutURL = options.logoutURL, message = options.message;
var timer;
return {
start: function(){
timer = setInterval(function(){
if (confirm(message)) {
$.get("renewSession.php");
}
else {
clearInterval(timer);
window.location.href = logoutURL;
}
}, seconds * 1000);
}
};
};
var myTimer = new ReloadTimer({
seconds: 20,
logoutURL: 'logout.php',
message: 'Do you want to stay logged in?'
});
myTimer.start();
You could execute the function again with the same parameters?
I use the following code to create countdowns in Javascript. n is the number of times to repeat, freq is the number of milliseconds to wait before executing, funN is a function to call on each iteration (typically a function that updates part of the DOM) and funDone is the function to call when the countdown is complete.
function timer(n, freq, funN, funDone)
{
if(n == 0){
funDone();
}else{
setTimeout(function(){funN(n-1); timer(n-1, freq, funN, funDone);}, freq);
}
}
It can be called like so:
timer(10,
1000, /* 1 second */
function(n){console.log("(A) Counting: "+n);},
function() {console.log("(A) Done!");}
);
timer(10,
500,
function(n){console.log("(B) Counting: "+n);},
function() {console.log("(B) Done!");}
);
The advantage of this is that I can call timer() as many times as I want without worrying about global variables etc. Is there a better way to do this? Is there a clean way to make setInterval stop after a certain number of calls (without using global variables)? This code also creates a new lambda function with each call to setTimeout which seems like it could be problematic for large countdowns (I'm not sure how javascript's garbage collector handles this).
Is there a better way to do this? Thanks.
This is basically the same idea as #balabaster, but it is tested, uses prototype, and has a little more flexible interface.
var CountDownTimer = function(callback,n,interval) {
this.initialize(callback,n,interval);
}
CountDownTimer.prototype = {
_times : 0,
_interval: 1000,
_callback: null,
constructor: CountDownTimer,
initialize: function(callback,n,interval) {
this._callback = callback;
this.setTimes(n);
this.setInterval(interval);
},
setTimes: function(n) {
if (n)
this._times = n
else
this._times = 0;
},
setInterval: function(interval) {
if (interval)
this._interval = interval
else
this._interval = 1000;
},
start: function() {
this._handleExpiration(this,this._times);
},
_handleExpiration: function(timer,counter) {
if (counter > 0) {
if (timer._callback) timer._callback(counter);
setTimeout( function() {
timer._handleExpiration(timer,counter-1);
},
timer._interval
);
}
}
};
var timer = new CountDownTimer(function(i) { alert(i); },10);
...
<input type='button' value='Start Timer' onclick='timer.start();' />
I'd create an object that receives a counter and receives a function pointer to execute, something akin to the following pseudo code:
TimedIteration = function(interval, iterations, methodToRun, completedMethod){
var counter = iterations;
var timerElapsed = methodToRun; //Link to timedMethod() method
var completed = callbackMethod;
onTimerElapsed = function(){
if (timerElapsed != null)
timerElapsed();
}
onComplete = function(){
if (completed != null)
completed();
}
timedMethod = function(){
if (counter != null)
if (counter > 0) {
setTimeOut(interval, onTimerElapsed);
counter--;
}
else
onComplete();
this = null;
}
}
if ((counter != null)&&(counter > 0)){
//Trip the initial iteration...
setTimeOut(interval, timedMethod);
counter--;
}
}
obviously this is pseudo code, I've not tested it in an IDE and syntactically I'm not sure if it'll work as is [I'd be astonished if it does], but basically what you're doing is you're creating a wrapper object that receives a time interval, a number of iterations and a method to run upon the timer elapsed.
You'd then call this on your method to run like so:
function myMethod(){
doSomething();
}
function doWhenComplete(){
doSomethingElse();
}
new TimedIteration(1000, 10, myMethod, doWhenComplete);
I like your original solution better than the proposed alternatives, so I just changed it to not create a new function for every iteration (and the argument of fun() is now the value before decrement - change if needed...)
function timer(n, delay, fun, callback) {
setTimeout(
function() {
fun(n);
if(n-- > 0) setTimeout(arguments.callee, delay);
else if(callback) callback();
},
delay);
}