您正在对动画进行排队,但永远不会将执行“让给”回浏览器,因为您只是立即再次调用该函数。
浏览器永远不会进入它的事件循环,动画也不会开始。
要解决此问题,您需要让浏览器等待所有动画完成,然后再次将它们排队:
$(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
});
我注意到您的四个独立效果可能应该串联运行,但.promise()
如果它们都并行运行,上述基于解决方案也将起作用。
见http://jsfiddle.net/alnitak/ZKevs/
请注意,如果您打算连续运行这些效果,您实际上不应该将它们全部排列在一起 - 没有时间保证,并且下一个元素可能会在前一个元素完成之前开始动画。
对此的传统解决方案是在最后一个动画中添加一个“动画完成”回调,但是像您在这里使用的四个单独的动画最终会被可怕地嵌套。
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'));