views:

89

answers:

7

Hi guys,

If I have an active timeout running that was set through var t = setTimeout("dosomething()", 5000),

Is there anyway to pause and resume it?


Is there any way to get the time remaining on the current timeout?
or do I have to in a variable, when the timeout is set, store the current time, then we we pause, get the difference between now and then?

+1  A: 

I don't think you'll find anything better than clearTimeout. Anyway, you can always schedule another timeout later, instead 'resuming' it.

Nikita Rybak
+6  A: 

No. You'll need cancel it (clearTimeout), measure the time since you started it and restart it with the new time.

RoToRa
+1  A: 

You could look into clearTimeout()

or pause depending on a global variable that is set when a certain condition is hit. Like a button is pressed.

  <button onclick="myBool = true" > pauseTimeout </button>

  <script>
  var myBool = false;

  var t = setTimeout(function() {if (!mybool) {dosomething()}}, 5000);
  </script>
John Hartsock
eval is evil. Don't pass strings to setTimeout...
Ivo Wetzel
+1  A: 

"Pause" and "resume" don't really make much sense in the context of setTimeout, which is a one-off thing. Do you mean setInterval? If so, no, you can't pause it, you can only cancel it (clearInterval) and then re-schedule it again. Details of all of these in the Timers section of the spec.

// Setting
var t = setInterval(doSomething, 1000);

// Pausing (which is really stopping)
clearInterval(t);
t = 0;

// Resuming (which is really just setting again)
t = setInterval(doSomething, 1000);
T.J. Crowder
+4  A: 

You could wrap window.setTimeout like this, which I think is similar to what you were suggesting in the question:

function Timer(callback, delay) {
    var timerId, start, remaining = delay;

    this.pause = function() {
        window.clearTimeout(timerId);
        remaining -= new Date() - start;
    };

    this.resume = function() {
        start = new Date();
        timerId = window.setTimeout(callback, remaining);
    };

    this.resume();
}

var timer = new Timer(function() {
    alert("Done!");
}, 1000);

timer.pause();
timer.resume();
Tim Down
+1 Same answer, faster on the draw! Point to you sir. :-)
Sean Vieira
A: 

Something like this should do the trick.

function Timer(fn, countdown) {
    var ident, complete = false;

    function _time_diff(date1, date2) {
        return date2 ? date2 - date1 : +new Date() - date1;
    }

    function cancel() {
        clearTimeout(ident);
    }
    function pause() {
        clearTimeout(ident);
        total_time_run = _time_diff(start_time);
        complete = total_time_run >= countdown;
    }
    function resume() {
        ident = complete ? -1 : setTimeout(fn, countdown - total_time_run );
    }

    var start_time = +new Date();
    ident = setTimeout(fn, countdown);

    return { cancel: cancel, pause: pause, resume: resume };
}
Sean Vieira
A: 

If you have several divs to hide, you could use an setInterval and a number of cycles to do like in:

<div id="div1">1</div><div id="div2">2</div>
<div id="div3">3</div><div id="div4">4</div>
<script>
    function hideDiv(elm){
        var interval,
            unit = 1000,
            cycle = 5,
            hide = function(){
                interval = setInterval(function(){
                    if(--cycle === 0){
                        elm.style.display = 'none';
                        clearInterval(interval);
                    }
                    elm.setAttribute('data-cycle', cycle);
                    elm.innerHTML += '*';
                }, unit);
            };
        elm.onmouseover = function(){
            clearInterval(interval);
        };
        elm.onmouseout = function(){
            hide();
        };
        hide();
    }
    function hideDivs(ids){
        var id;
        while(id = ids.pop()){
            hideDiv(document.getElementById(id));
        }
    }
    hideDivs(['div1','div2','div3','div4']);
</script>
Mic