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?
Related
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)
Right now i have this 1 minute timer in my background page that runs forever i would like to be able to start and stop it from an options page.
chrome.browserAction.setBadgeBackgroundColor({color:[0, 0, 0, 255]});
var i = 1;
window.setInterval(function(timer) {
chrome.browserAction.setBadgeText({text:String(i)});
i++;
}, 60000);
setInterval() method of the Window object schedules a function to be invoked repeatedly at intervals of the specified number of milliseconds. setInterval() returns an opaque value that can be passed to clearInterval() to cancel any future invocations of the scheduled function. Read more about How Javascript Timers work. With that you can write something like this:
My.Controller = {};
(function() {
var interval = 10;
var timer = null;
function init (param) {
// initialisations if any
}
// Override the default interval of 10 seconds by passing new interval
function startAction (param, tInterval) {
// Set a timer
var ti = (!tInterval) ? interval : tInterval;
timer = setInterval(My.Controller.action, ti * 2000);
}
function action () {
// Logic here
}
function stopAction () { clearInterval(timer); }
var c = My.Controller;
c.init = init;
c.startAction = startAction;
c.stopAction = stopAction;
})(); // end Controller
Now you can say My.Controller.startAction() to start the timer and and My.Controller.stopAction() to stop.
Read and explore about namespaces in JavaScript.
Hope this helps.
I have a setInterval function like below on a Divbox so if I leave a divbox, this setInterval is triggered:
setInterval("playthis()", 1000);
What I want it to do: If I leave the divbox and lets say within the next 2 second rehover it, the setInterval should not triggered.
Is this possible?
You can use cousins setTimeout and clearTimeout to set a function callback that invokes your setInterval only after 2 uninterrupted seconds:
var handle = null;
function yourDivboxLeaveHandler() {
handle = setTimeout(startPlay, 2000);
}
function yourDivboxHoverHandler() {
if (handle !== null) {
clearTimeout(handle);
handle = null;
}
}
function startPlay() {
setInterval(playthis, 1000); // use function references please, not eval
handle = null;
}
You will want much better variable/function names than this though.
Yes. Just make some creative use of clearInterval().
In other words, no, such a feature doesn't come out-of-the-box, but you can build it yourself by calling clearInterval() if the mouse re-enters the divbox before the interval is triggered.
For example:
var divBox = document.getElementById('MyDivBox');
var TimeoutHandle = null;
divBox.onmouseover = function()
{
if ( TimeoutHandle != null )
{
clearTimeout(TimeoutHandle);
}
}
divBox.onmouseout = function()
{
TimeoutHandle = setTimeout(function()
{
TimeoutHandle = null;
setInterval(playthis, 1000);
}, 2000);
}
First of all is a bad practice to have the code evalued in a setInterval so you should avid double quotes. Then you can clear the interval like this:
var int = setInterval(playthis, 1000);
clearInterval(int)
If I have the following code:
var myfunc = function() { alert('wow'); };
var t=setTimeout(myfunc, 300);
Is there anything I can do with the id stored in t to verify the timer's duration and callback? I'm trying to verify the timer's properties directly so I don't have to actually run it 'till timeout in my unit tests.
Nope, can't be done.
What you can do instead is track them differently, something like this:
var timeouts = [{
fn: myfunc,
timeout: 300
}];
for(var i = 0; i < timeouts.length; i++){
timeouts[i].id = window.setTimeout(timeouts[i].fn, timeouts[i].timeout);
}
The returned ID is internal to the browser, so you can't do much with it. But since you know the duration and callback when you initiate the timer, you could just as well wrap the whole thing in a Timer class that does everything for you:
function Timer(callback, timeout) {
this.callback = callback;
this.timeout = timeout;
this.id = window.setTimeout(callback, timeout);
}
Timer.prototype.cancel = function() {
window.clearTimeout(this.id);
}
Timer.prototype.fire = function() {
this.cancel();
this.callback();
}
Then you just create timers and access their properties like this:
t = new Timer(myfunc, 300);
alert(t.timeout);
The window.setTimeout (and related setInterval) function in Javascript allows you to schedule a function to be executed sometime in the future:
id = setTimeout(function, delay);
where "delay" is the number of milliseconds into the future at which you want to have the function called. Before this time elapses, you can cancel the timer using:
clearTimeout(id);
What I want is to update the timer. I want to be able to advance or retard a timer so that the function gets called x milliseconds sooner or later than originally scheduled.
If there were a getTimeout method, you could do something like:
originally_scheduled_time = getTimeout(id);
updateTimeout(id, originally_schedule_time + new_delay); // change the time
but as far as I can tell there's nothing like getTimeout or any way to update an existing timer.
Is there a way to access the list of scheduled alarms and modify them?
Is there a better approach?
thanks!
If you really want this sort of functionality, you're going to need to write it yourself.
You could create a wrapper for the setTimeout call, that will return an object you can use to "postpone" the timer:
function setAdvancedTimer(f, delay) {
var obj = {
firetime: delay + (+new Date()), // the extra + turns the date into an int
called: false,
canceled: false,
callback: f
};
// this function will set obj.called, and then call the function whenever
// the timeout eventually fires.
var callfunc = function() { obj.called = true; f(); };
// calling .extend(1000) will add 1000ms to the time and reset the timeout.
// also, calling .extend(-1000) will remove 1000ms, setting timer to 0ms if needed
obj.extend = function(ms) {
// break early if it already fired
if (obj.called || obj.canceled) return false;
// clear old timer, calculate new timer
clearTimeout(obj.timeout);
obj.firetime += ms;
var newDelay = obj.firetime - new Date(); // figure out new ms
if (newDelay < 0) newDelay = 0;
obj.timeout = setTimeout(callfunc, newDelay);
return obj;
};
// Cancel the timer...
obj.cancel = function() {
obj.canceled = true;
clearTimeout(obj.timeout);
};
// call the initial timer...
obj.timeout = setTimeout(callfunc, delay);
// return our object with the helper functions....
return obj;
}
var d = +new Date();
var timer = setAdvancedTimer(function() { alert('test'+ (+new Date() - d)); }, 1000);
timer.extend(1000);
// should alert about 2000ms later
I believe not. A better approach might be to write your own wrapper which stores your timers (func-ref, delay, and timestamp). That way you can pretend to update a timer by clearing it and calculate a copy with an updated delay.
Another wrapper:
function SpecialTimeout(fn, ms) {
this.ms = ms;
this.fn = fn;
this.timer = null;
this.init();
}
SpecialTimeout.prototype.init = function() {
this.cancel();
this.timer = setTimeout(this.fn, this.ms);
return this;
};
SpecialTimeout.prototype.change = function(ms) {
this.ms += ms;
this.init();
return this;
};
SpecialTimeout.prototype.cancel = function() {
if ( this.timer !== null ) {
clearTimeout(this.timer);
this.timer = null;
}
return this;
};
Usage:
var myTimer = new SpecialTimeout(function(){/*...*/}, 10000);
myTimer.change(-5000); // Retard by five seconds
myTimer.change(5000); // Extend by five seconds
myTimer.cancel(); // Cancel
myTimer.init(); // Restart
myTimer.change(1000).init(); // Chain!
It may be not exactly what you want, but take a look anyway, maybe you can use it to your benefit.
There is a great solution written by my ex-coworker that can create special handler functions that can stop and start timeouts when required. It is most widely used when you need to create a small delay for hover events. Like when you want to hide a mouseover menu not exactly at the time when a mouse leaves it, but a few milliseconds later. But if a mouse comes back, you need to cancel the timeout.
The solution is a function called getDelayedHandlers. For example you have a function that shows and hides a menu
function handleMenu(show) {
if (show) {
// This part shows the menu
} else {
// This part hides the menu
}
}
You can then create delayed handlers for it by doing so:
var handlers = handleMenu.getDelayedHandlers({
in: 200, // 'in' timeout
out: 300, // 'out' timeout
});
handlers becomes an object that contains two handler functions that when being called cancel the other one's timeout.
var element = $('menu_element');
element.observe('mouseover', handlers.over);
element.observe('mouseout', handlers.out);
P.S. For this solution to work you need to extend the Function object with the curry function, which is automatically done in Prototype.
One possibility can be like this:
if (this condition true)
{
setTimeout(function, 5000);
}
elseif (this condition true)
{
setTimeout(function, 10000);
}
else
{
setTimeout(function, 1000);
}
It's up to your how you construct your conditions or the logic. thanks