one2gov one2gov - 1 year ago 129
Javascript Question

jQuery setInterval lag

I am using this jQuery code in my project

$(window).load(function() {
setInterval('shiftLeft()', 3000);

// arrange the boxes to be aligned in a row
function arrangeBoxes() {
$('.box').each( function(i, item) {
var position = $('#window').position().left + 3 + i * ( $(item).width() + 10 );
$(item).css('left', position+'px')

// shifts all the boxes to the left, then checks if any left the window
function shiftLeft() {
$('.box').animate({'left' : "-=100px"}, 3000, 'linear', checkEdge());

// returns the new location for the box that exited the window
function getNewPosition() {
return $('.box:last').position().left + $('.box:last').outerWidth() + 10;

// if the box is outside the window, move it to the end
function checkEdge() {
var windowsLeftEdge = $('#window').position().left;

$('.box').each( function(i, box) {
// right edge of the sliding box
var boxRightEdge = $(box).position().left + $(box).width();

// position of last box + width + 10px
var newPosition = getNewPosition();

if ( parseFloat(boxRightEdge) < parseFloat(windowsLeftEdge) ) {
$(box).css('left', newPosition);
first = $('.box:first').attr('class');

With so many elements every 3 seconds I am getting that little annoying lag.

I think I can slice every element, except first few and store them somewhere for a while. But I really don't know how to do it.

Of course I can append them to an invisible div and them take them from it, but I think it's nasty. So where should I store so many objects?


Answer Source

You can't get any sort of guaranteed precision from JavaScript (browser) timers, but you can adapt to conditions as they change by using setTimeout() instead of setInterval() and computing each timeout adaptively.

The basic mechanism looks like:

function adaptiveTimer(interval, worker) {
  function tick() {
    setTimeout(tick, (previous += interval) -;

  var previous =;

The "adaptiveTimer" function takes an interval (in milliseconds here) and a worker function that'll do whatever work you want done on each interval. The function (the outer one) notes the current wall clock time and runs the inner "tick" function for the first cycle.

The "tick" function runs the worker. It then checks the wall clock time again, and computes how many milliseconds there are between the current time and the nominal time at which the next cycle should run. That difference is used as the timeout value for the next iteration.

If the worker takes more or less time to run, that calculation will adapt the timeout intervals to (somewhat) make up for the changes.