2012-11-13 40 views
1

我有一个jQuery动画,我想循环无限,我有当前的代码,但它只是没有返回。循环通过jQuery函数InWitly

$(document).ready(function() { 
     var i = 0; 
     document.write(i); 

     function runTest(){ 
      $('#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); 
      i++; 
      runTest(); 
     } 

     if(i === 0){ 
     runTest(); 
     } 


    }); 

很多谢谢! :)

+0

不能使用加载页面后的'document.write' ...会清除内容 – charlietfl

回答

1

您可以包装他们所有的功能,并重新呼叫上次动画结束后的功能:

function run(){ 

     $('#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,run); 
} 

run(); 

活生生的例子:http://jsfiddle.net/nCs6N/

+0

工作,太棒了! :-) –

0

首先,你不应该链动画这样的,使用回调:

$("#page_effect").fadeIn(1500, function() { 
    $(this).delay(3500).fadeOut(1500); 
}); 

这将等待3500ms到淡出,但只有1500毫秒后淡入完成。 这种方式使用的回调,可以从上次回调再次调用该函数:

function runTest(){ 

    ... 

    $('#page_effect4').delay(21000).fadeIn(1500, function() { 
     $(this).delay(3500).fadeOut(1500, function() { 
       runTest(); 
       // this will be called only after the fadeout completes 
     }); 
    }); 
} 
+0

你在做什么?jQuery动画函数被特别设计为像这样链接。有点破的一点是,他在下一个元素上开始动画,并不保证前一个元素完成。 – Alnitak

+0

看着代码和延迟变得越来越大(高达21000)与每一个淡出我假设这些应该发生在继承,所以更好的方法是使用回调。以这种方式控制一系列动画效果会更加高效,它可以计算您的头部延迟。我使用的符号主要是为了介绍回调并显示它们如何以友好的方式工作:) –

+0

从你的回答中,你完全不清楚你是在谈论四个元素上每个动画之间的延迟。你已经结束了乱七八糟的链接和非链接调用混乱。 – Alnitak

0

你排队的动画,但从来没有“屈服”的执行返回给浏览器,因为你立即再次调用该函数。

浏览器永远不会进入其事件循环,并且动画不会启动。

要解决这个问题,你需要使浏览器等到所有的动画已经完成,并然后再次排队它们:

$(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')); 
-1

不要像这样递归调用runTest(),你会耗尽函数堆栈。

而是使用setTimeout(runTest, 0);