アニメーションをキューに入れていますが、すぐに関数を再度呼び出すだけなので、実行をブラウザに「譲る」ことはありません。
ブラウザはイベント ループに入ることができず、アニメーションは開始されません。
これを修正するには、すべてのアニメーションが完了するまでブラウザを待機させてから、再度キューに入れる必要があります。
$(function() {
(function animate() {
$('#page_effect').fadeIn(1500).delay(3500).fadeOut(1500);
$('#page_effect2').delay(7000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#page_effect3').delay(13900).fadeIn(1500).delay(3500).fadeOut(1500);
$('#page_effect4').delay(21000).fadeIn(1500).delay(3500).fadeOut(1500);
// using deferred objects, ask for a promise that will be resolved
// when all animations on the specified elements have been completed,
// and when done, call myself to start all over again
$('#page_effect,#page_effect2,#page_effect3,#page_effect4')
.promise().done(animate);
})(); // invoke immediately
});
4 つの個別のエフェクトはおそらく直列に実行されるはずですが、.promise()
上記のベース ソリューションは、それらがすべて並列に実行されている場合にも機能します。
http://jsfiddle.net/alnitak/ZKevs/を参照してください。
これらのエフェクトを連続して実行する場合は、それらをすべて一緒にキューに入れるべきではないことに注意してください。タイミングの保証はなく、前の要素が終了する前に次の要素がアニメーションを開始する可能性があります。
これに対する従来の解決策は、最後のアニメーションに「アニメーション完了」コールバックを追加することでしたが、ここにあるように 4 つの個別のアニメーションを使用すると、恐ろしくネストされてしまいます。
ここでも jQuery 遅延オブジェクトが役立ちます。これにより、追加の計算.delay()
呼び出しがどのように排除されるかに注意してください。
$('#page_effect').fadeIn(1500).delay(3500).fadeOut(1500);
$('#page_effect').promise().done(function() {
$('#page_effect2').fadeIn(1500).delay(3500).fadeOut(1500);
});
$('#page_effect2').promise().done(function() {
$('#page_effect3').fadeIn(1500).delay(3500).fadeOut(1500);
});
$('#page_effect4').promise().done(function() {
$('#page_effect4').fadeIn(1500).delay(3500).fadeOut(1500);
});
$('#page_effect4').promise.done(animate);
この時点で、すべてのアニメーション チェーンが同一であり、リファクタリングできることがわかります。
function cycle($els) {
var i = 0, n = $els.length;
(function next() {
var $this = $els.eq(i);
i = (i + 1) % n;
$this.fadeIn(1500).delay(3500).fadeOut(1500).promise().done(next);
})();
});
cycle($('#page_effect,#page_effect2,#page_effect3,#page_effect4'));