1

我有一个 jQuery 动画,我想无限循环,我有当前代码,但它什么也不返回。

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


     });

非常感谢!:)

4

4 回答 4

0

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

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

这将等待 3500 毫秒淡出,但仅在 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
         });
    });
}
于 2012-11-13T11:11:51.757 回答
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'));
于 2012-11-13T11:12:01.343 回答
0

您可以将它们全部包装在一个函数中,并在最后一个动画完成后重新调用该函数:

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/

于 2012-11-13T11:13:58.740 回答
-1

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

而是使用setTimeout(runTest, 0);

于 2012-11-13T11:12:37.587 回答