English 中文(简体)
JavaScript getTimeout?
原标题:

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





相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签