Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add duration to JS setTimeout after the timer is running

Tags:

javascript

I'm trying to figure out a way to emulate AS3's Timer class.

If you're not familiar, one of the cool things you can do is add duration to the timer even if it's already running. This functionality has a lot of very nice uses.

Anyone have any thoughts on doing this in js?

like image 609
Jonathan Dumaine Avatar asked Oct 17 '11 19:10

Jonathan Dumaine


3 Answers

Clear the timeout, then set a new timeout to the new desired end time.

like image 147
SLaks Avatar answered Oct 19 '22 10:10

SLaks


I'm not familiar with this class, but you can easily create something similar in JavaScript:

function Timer(callback, time) {
    this.setTimeout(callback, time);
}

Timer.prototype.setTimeout = function(callback, time) {
    var self = this;
    if(this.timer) {
        clearTimeout(this.timer);
    }
    this.finished = false;
    this.callback = callback;
    this.time = time;
    this.timer = setTimeout(function() {
         self.finished = true;
        callback();
    }, time);
    this.start = Date.now();
}

Timer.prototype.add = function(time) {
   if(!this.finished) {
       // add time to time left
       time = this.time - (Date.now() - this.start) + time;
       this.setTimeout(this.callback, time);
   }
}

Usage:

var timer = new Timer(function() { // init timer with 5 seconds
    alert('foo');
}, 5000);

timer.add(2000); // add two seconds
like image 12
Felix Kling Avatar answered Oct 19 '22 10:10

Felix Kling


Wrap the function with another one, and when the timer runs out, test to see if an extra time variable has been set. If it has, start again with the new time, otherwise execute the function.

A quickly hacked together script might look like:

function test() {
    tim = new timer(function () { alert('hello'); }, 5000);   
}

function extend() {
    if (tim) { tim.addTime(5000); }   
}

function timer(func, time) {
    var self = this,
        execute = function () {
            self.execute()  
        };
    this.func = func;
    this.extraTime = 0;
    setTimeout(execute, time);
};

timer.prototype.execute = function () {
    var self = this,
        execute = function () {
            self.execute()  
        };
    if (this.extraTime) {
        setTimeout(execute, this.extraTime);
        this.extraTime = 0;
    } else {
        this.func();   
    }
};

timer.prototype.addTime = function (time) {
    this.extraTime += time;   
}

<input type="button" value="Start" onclick="test()">
<input type="button" value="Extend" onclick="extend()">
like image 3
Quentin Avatar answered Oct 19 '22 10:10

Quentin