nickMiddleweek.blog.search();

Monday, 15 October 2012

How to change the interval duration in JavaScript with .startDualTimer(d1, d2);

Now there are times when you'll need to kick off a setInterval() timer and modify the duration (or interval timer) after it has started perhaps so the first is different from the n+1 duration. For me, this cropped up recently with a animated image scroller component where we had three timers overall which controlled when to load in a new image and animate them to the left. To start with I just kicked off a standard setInterval() with 7000 milliseconds but this meant the user could potentially wait 14+ seconds for an update which isn't always ideal so we defined the following timers:
  1. Initial component start timer (7000 ms).
  2. IDLE timer, or the default loop timer (5000 ms).
  3. After Interaction timer (3000 ms), so if you moused over the component, I'd pause the animation but we wanted this quicker interval so the user wasn't left waiting for that potential 14+ seconds...
Now there is no way of modifying the duration of a setInterval() once it's started but we can replicate exactly what is required by using setTimeout and a recursive function. I can think of a couple of ways to achieve this, some perhaps being more generic but here's the code I implemented for this particular component...
com.middleweek.strip.prototype.startDualTimer = function (firstDelay, ongoingDelay) {
 "use strict";
 var self = this;
 if (self._internal.timer === null) { // Only start the timer if it's not already started...

  var timeoutHandler = function () {
   "use strict";
   if (self._internal.timer) { // Check to see if it's been stopped.
    self.timerInternalEventHandler();
   }
   self._internal.timer = window.setTimeout(timeoutHandler, ongoingDelay);
  };
 self._internal.timer = window.setTimeout(timeoutHandler, firstDelay);
 }
}
It's all pretty self-explanatory but here we have a function that accepts two values, firstDelay and ongoingDelay. The first call to setTimeout uses the firstDelay which invokes it's private closure function timeoutHandler() which in turns calls the components timerInternalEventHandler() function to do it's magic and then it continues to recursively call the private closure with ongoingDelay, and so forth...

At any time, we can call clearTimeout(self._internal.timer) and then set it to null to cease the magic.

...setInterval's best friend!

No comments:

Post a comment

The internet is a crazy place so please help us keep it under control by leaving only relevant messages and comments, thanks a bunch! :m)