我使用jquery为html元素(卡片)制作动画。我需要为交易动作制作动画('一个是你的,一个是我,一个是你,一个是我......')所以想要在下一个开始之前完全动画(移动位置)。我在$ .each函数中创建卡片并从那里调用动画(以避免不必要的循环)。当卡片添加到页面时,动画开始,但循环然后移动到下一张卡片而不等待动画完成。这使得所有卡片看起来在完全相同的时间而不是顺序地动画。如何让循环等待动画回调?这可以用触发器来完成吗?我可以手动排队项目吗?
我的(错误的)代码的缩减版本:
var card = [
{ id:1, pos:{ x:100, y:100 } },
{ id:2, pos:{ x:150, y:105 } },
{ id:3, pos:{ x:200, y:110 } }
];
$.each(card, function() {
$('#card_' + this.id).animate({ top:this.pos.y, left:this.pos.x });
});
答案 0 :(得分:4)
您无法在JavaScript循环中执行此操作,您必须使用animate
调用上的回调参数来触发下一张卡片的动画。像这样:
var card = [
{ id:1, pos:{ x:100, y:100 } },
{ id:2, pos:{ x:150, y:105 } },
{ id:3, pos:{ x:200, y:110 } }
];
doOne(0);
function doOne(index) {
var thisCard = card[index];
if (thisCard) {
$('#card_' + thisCard.id).animate({
top: thisCard.pos.y,
left: thisCard.pos.x
}, function() {
doOne(index + 1);
});
}
}
Here's a live example当然,我将所有这些都包含在一个函数中,以避免创建不必要的全局符号。
答案 1 :(得分:2)
您可以使用.delay()
,如下所示:
$.each(card, function(i) {
$('#card_'+this.id).delay(i*400).animate({ top:this.pos.y, left:this.pos.x });
});
Here's your updated/working demo
每个动画(默认情况下)需要400毫秒,$.each()
回调的第一个参数是索引,因此第一个延迟0 * 400,第二个1 * 400等...有效运行它们一个接一个。
此外,如果您 需要那些x
/ y
格式变量,您可以将它们存储为top
/ left
并传递那些动画属性直接,如下:
var card = [
{ id:1, pos:{ left:100, top:100 } },
{ id:2, pos:{ left:150, top:105 } },
{ id:3, pos:{ left:200, top:110 } }
];
$.each(card, function(i) {
$('#card_'+this.id).delay(i*400).animate(this.pos);
});
答案 2 :(得分:1)
这是另一种方法:
var card = [
{elem: $('#card_1'), id:1, pos:{ x:100, y:100 } },
{elem: $('#card_2'), id:2, pos:{ x:150, y:105 } },
{elem: $('#card_3'), id:3, pos:{ x:200, y:110 } }
];
(function loop(arr, len){
if(len--){
arr[len].elem.animate({top: arr[len].pos.y, left: arr[len].pos.x}, 400, function(){
loop(arr, len);
});
}
}(card.reverse(), card.length));
答案 3 :(得分:0)
这可能会使正常的回调变得混乱,因为每个动画需要在其回调中调用下一个。当然,您可以使用计时器或延迟来创建暂停,但这并不能保证在下一个动画开始之前完整动画完成。如果动画花费的时间少于超时时间,则每个动画之间可能会有一个暂停。
另一种选择是研究承诺和期货。虽然我没有执行动画,但我的应用程序具有必须按特定顺序处理的逻辑。我一直在使用FuturesJS库来帮助简化操作。起初它可能看起来令人生畏,但它确实非常强大。看一下.chainify()
方法。
我意识到这对你的简单用例来说可能有些过分,但我相信了解Promise是值得的。