2012-02-27 3 views
5

я не могу использовать функции обратного вызова, потому что у меня есть сценарий вроде этого (псевдо-код):Синхронная анимация в jQuery, не используя обратные вызовы?

$('.box').on('click', function() { 
    $('.expanded-box').animate({ 
     // shrink it 
    }); 

    $(this).animate({ 
     // grow it 
     $(this).addClass('expanded-box'); 
    }); 
}); 

Я не могу поставить анимацию расширения в функции обратного вызова для анимации expanded-box роста, потому что не всегда может случиться , Но мне нужна вторая анимация, чтобы подождать, пока предыдущий не будет выполнен. Как я могу это сделать?

+0

Что вы имеете в виду под «не всегда может случиться.»? Вы имеете в виду, что '.expanded-box' может и не существовать? –

ответ

7

С JQuery 1.6, вы можете использовать promise() для получения Promise object, что будет разрешена, когда все анимации на заданном элементе будут завершены. Кроме того, в документации указано:

Использование .promise() в коллекции без активной анимации возвращает Решение обещание.

Таким образом, он хорошо подходит для вашего случая использования, и вы можете написать:

$('.box').on('click', function() { 
    var $this = $(this); 
    $('.expanded-box').animate({ 
     // shrink it 
    }).promise().done(function() { 
     $this.animate({ 
      // grow it 
     }).addClass('expanded-box'); 
    }); 
}); 
+0

Прохладный, даже не знал о 'обещании()' - спасибо! Он работает и на множестве разных методов. – CaptSaltyJack

+0

Как это отличается от размещения второй части в полном обратном вызове первой анимации? – nnnnnn

+1

@nnnnnn, если '$ (". Расширенный-box ")' ничего не соответствует, обратный вызов 'complete' не будет вызываться, так как он вызывается один раз для каждого согласованного элемента. С другой стороны, 'обещание()' возвращает разрешенный объект 'Promise', если вызывается на пустой объект jQuery, поэтому, чтобы функция, переданная' done() ', вызывалась во всех случаях (т. Е. Даже при первом щелчке, когда ящик еще не расшифрован). –

1

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

$('.box').on('click', function() { 
    var $this = $(this), 
     $exp = $(".expanded-box"); 

    function grow() { 
     $this.animate({ 
      width: "200px", height: "100px" 
     }).addClass('expanded-box'); 
    } 

    if ($exp.length > 0) { 
     $exp.animate({ 
      width: "100px", height: "50px" 
     }, grow).removeClass("expanded-box"); 
    } else { 
     grow(); 
    }   
});​ 

Демо: http://jsfiddle.net/PXddm/

+0

Прохладный. Я подумал об этом, но надеялся на более элегантное решение. Я думал, что в jQuery есть какая-то функция очереди анимации. – CaptSaltyJack

+0

Существует определенная функция очереди анимации. Он применялся только для каждого элемента, но «Начиная с jQuery 1.7, опция очереди также может принимать строку, и в этом случае анимация добавляется в очередь, представленную этой строкой». - но я никогда не использовал эту функцию, поэтому я точно не знаю, как это работает. – nnnnnn