0

我使用 jquery transit 插件制作了一个用于动画的小测试代码。

该脚本的目的是让塔的照片向用户翻转 90 度,切换到另一个塔图像,然后再翻转 90 度以平放在屏幕上。问题是,在第一次 90 度翻转后,图像完全消失,直到 for 循环结束,然后才进行最后一次翻转作为第二张图像。我希望它不断翻转,直到循环完成。

我想这与闭包和范围有关......

Javascript:

$(function() {
 for (var i = 0; i < 10; i++) {
  $('#test_flip')
   .css('background-image', 'url("tower1.jpg")')
   .transition({
    rotateY: '90deg'
   }, function() {
    $('#test_flip')
     .css('background-image', 'url("tower2.jpg")')
     .transition({
      rotateY: '180deg'
     });
   });
 };
});

jsfiddle:http: //jsfiddle.net/ce9b9aja/

4

1 回答 1

0

问题在于 for 循环连续调用了.transition10 次。调用queued在 jQuery 队列中(由 transit.js 在幕后完成),但它们没有按照您期望的顺序排队。

举个例子:

$(function () {
    $('#test').transition({x:40}, function () {
        $(this).transition({y:40});
    })
    
    $('#test').transition({scale:0.5}, function() {
        $(this).transition({skewX:"50deg"});
    });
});
#test {
    width: 10em;
    height: 10em;
    background-color: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://ricostacruz.com/jquery.transit/jquery.transit.min.js"></script>
<div id="test"></div>

在这个例子中,第一个转换x:40将立即执行,因为没有队列。尽管它是立即执行的,但由于它是一个动画,它将使用某种形式的setTimeoutorsetInterval并且不会transition方法调用中完成。因此,将在转换仍在动画scale:0.5时调用转换,这会将其放入队列中,然后将其放入队列中。x:40y:40

因此,队列顺序为

x:40 -> scale:0.5 -> y:40 -> skewX:50deg

同样,您的代码正在生成以下队列:

rotateY:90deg -> ... -> rotateY:90deg -> rotateY:180deg -> ... -> rotateY:180deg

因此您的代码的行为。它首先旋转图像90deg,然后再旋转 9 次,这不会在视觉上改变任何东西(因此是“暂停”)。然后它会改变图像并旋转它,然后再旋转180deg9 次。

一种解决方案是使用函数的回调创建递归.transition函数。下面实现了一个示例:

$(function() {
    FlipMe($('#test_flip'), "http://i.imgur.com/tYYtwbi.jpg", "http://i.imgur.com/G4CvJpc.jpg", 10)
});

function FlipMe($el, image1, image2, times) {
    $el.css('background-image', 'url("'+image1+'")')
        .transition({rotateY: '90deg'}, function() {
                $el.css('background-image', 'url("'+image2+'")')
                .transition({rotateY: '180deg'}, function() {
                    if(times > 0) {
                        FlipMe($el, image2, image1, times - 1);
                    }
                });
    });
}

在这里更新小提琴:http: //jsfiddle.net/ce9b9aja/1/

上面的代码专门使用回调函数来指示事件的顺序。当第一个转换完成时,回调函数将“排队”下一个转换,它将立即执行,因为队列中不会有其他任何东西。等等。

于 2014-09-02T21:20:53.710 回答