2013-12-17 4 views
0

Я пытаюсь сделать анимацию для анимации один за другим.Анимация полная бесконечная петля в jQuery

То, как я сделал это было так:

$(class).animate(
    {something}, 
    { 
     duration: 1000, 
     complete: function(){ 
         $(class).animate(
          {something}, 
          { 
           duration: 1000, 
           complete: function(){ 
           // More to animate when previous animation is done 
          } 
        }); 
    } 
}); 

До сих пор это работало достаточно хорошо. Моя проблема заключается в следующем:

Чтобы запустить эту цепочку анимаций, я нажимаю на элемент. Когда вы нажимаете на этот элемент, существует переменная «continue», которая становится истинной, поэтому невозможно вернуться к этому элементу, потому что конец анимации еще не достигнут.

Глубокая анимация в этой цепочке анимаций следующая.

complete: function(){ 
    $(few divs).each(function(){ 
     $(this).delay(delay).animate(
      {"opacity": 1}, 
      { 
       duration:2000, 
       complete: function(){ 
         console.log(i + " finished"); // 
         if(i == 2){ // 3 divs 
          ongoing = false; // All the animations are finished, allowed to reclick 
         } 
       } 
       delay += 2000; 
      }); 
} 

Проблема в том, что он показывает 3 раза 0,1,2.

0 finished 
1 finished 
2 finished 
0 finished 
1 finished 
2 finished 
0 finished 
1 finished 
2 finished 

Затем я попытался это:

complete: function(){ 
    selected = text; 

    $(few divs).each(function(i){ 
     $(this).delay(delay).animate({"opacity": 1}, 2000); 
     delay += 2000; 
    }).promise().done(function(){ // All each's are finished 
     ongoing = false; 
     console.log("finished"); 
    }); 
} 

В этом примере есть также бесконечный цикл с «закончил» ...

Что именно происходит в моем коде и почему он не работает?

+0

Вы пытались сделать вызов рекурсивно вместо жесткого кодирования каждого уровня? Кроме того, почему бы не включить функцию в качестве обратного вызова, а не в завершенное событие, как показано далее на странице на странице [jQuery animate] (http://api.jquery.com/animate/) – Loyalar

+0

Нет, я не пробовал но я буду. Знаете ли вы, в чем разница между функцией обратного вызова и полным параметром функции animate? – oxynad

+0

На самом деле, насколько я могу читать, похоже, нет никакой разницы. Я никогда не видел, чтобы кто-то помещал функции в событие Complete, а не просто как обычный обратный вызов. – Loyalar

ответ

0

}).promise().done(function(){ // all each's are finished

Это неправильно - это всегда сразу же выполняется.

Вам нужно нажать отложенные объекты вашего animate() в массив; рассмотрим следующий пример.

var promises = []; 
$(few divs).each(function(i){ 
    promises.push(
     $(this) 
      .delay(i * 2000) 
      .animate({ 
       "opacity": 1 
      }, 2000) 
    ); 
}) 
$.when.apply($, promises).done(function() {}); 
+1

В вашем 'apply' отсутствует первый параметр' thisArg'. –

+0

@oxynad Вы не можете просто сказать, что что-то не работает. По крайней мере, отправьте код. И если вы используете 'console.log()', почему бы не поместить это в тонны мест, чтобы вы могли заметно увидеть порядок выполнения событий? Предоставляемый мною фрагмент кода будет выполнять только один раз «done()», если только весь фрагмент не вызывается несколько раз. –

+0

Я добавил console.log в функцию(), и по какой-то причине он показал 3 «законченных» примерно через 6 секунд после завершения анимации. Почему это? Я буду тестировать еще – oxynad

0

«увеличение задержки» подход на самом деле дает набор отдельных анимации каждый с прогнозируемым временем начала, чтобы дать эффект последовательности из конца в конец - с потенциалом для ошибок синхронизации.

Лучшим подходом было бы создание подлинной последовательности анимации с гарантированным timimg путем создания цепи .then().

complete: function() { 
    var promise = $.when(); 
    $(few divs).each(function() { 
     promise = promise.then(function() { 
      return $(this).animate({'opacity': 1}, 2000).promise(); 
     }); 
    }); 
    promise.done(function() { // All animates are complete 
     ongoing = false; 
     console.log('finished'); 
    }); 
} 

Или, чуть более компактно, используя метод .reduce() массива:

complete: function() { 
    $(few divs).get().reduce(function(promise, el) { 
     return promise.then(function() { 
      return $(el).animate({'opacity': 1}, 2000).promise(); 
     }); 
    }, $.when()).done(function() { // All animates are complete 
     ongoing = false; 
     console.log('finished'); 
    }); 
} 
Смежные вопросы