2013-11-21 2 views
1

Я использую этот код JQuery в моем проекте http://jsbin.com/uceqi/357JQuery setInterval лаг

$(window).load(function() { 
    arrangeBoxes(); 
    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); 
      $(box).remove().appendTo('#window'); 
      first = $('.box:first').attr('class'); 
     } 
    }); 
} 

С таким количеством элементов, каждые 3 секунды я получаю, что немного раздражает запаздыванием.

Я думаю, что я могу срезать каждый элемент, кроме первых, и хранить их где-то некоторое время. Но я действительно не знаю, как это сделать.

Конечно, я могу добавить их в невидимый div, и они берут их с него, но я думаю, что это противно. Итак, где я должен хранить столько объектов?

Cookies?

+3

Я бы начал с того, что не использовал setInterval, я почему-то сомневаюсь, что анимация достаточно точная, чтобы закончить ровно 3 секунды, что может привести к увеличению очереди со временем. Кроме того, вы выполняете 'checkEdge' немедленно, а не когда анимация завершена. –

+0

Пожалуйста, имейте в виду, что на интервалы JS влияет загрузка процессора - таким образом, вполне вероятно, что это причина вашего запаздывания. – eithed

ответ

1

Вы не можете получить какую-либо гарантированную точность от JavaScript (браузера) таймеров, но вы можете адаптироваться к условиям по мере их изменения, используя setTimeout() вместо setInterval() и адаптируя каждый таймаут адаптивно.

Основной механизм выглядит следующим образом:

function adaptiveTimer(interval, worker) { 
    function tick() { 
    worker(); 
    setTimeout(tick, (previous += interval) - Date.now()); 
    } 

    var previous = Date.now(); 
    tick(); 
} 

Функция «adaptiveTimer» принимает интервал (в миллисекундах) здесь и функцию работник, который будет делать то, что работа, которую вы хотите сделать на каждом интервале. Функция (внешняя) отмечает текущее время настенных часов и запускает внутреннюю функцию «tick» для первого цикла.

Функция «галочка» запускает работника. Затем он снова проверяет время настенных часов и вычисляет, сколько миллисекунд существует между текущим временем и номинальным временем, в течение которого должен выполняться следующий цикл. Эта разница используется как значение тайм-аута для следующей итерации.

Если работник занимает больше или меньше времени для запуска, этот расчет будет адаптировать интервалы таймаута (в некоторой степени) для внесения изменений.