看看这个小提琴:http://jsfiddle.net/ym1aLk25/9/
var s = $('#shake');
var randomTran = function (flag) {
flag = flag || 0;
if (flag < 6) {
var rh = Math.floor((Math.random() * 10) - 5),
rv = Math.floor((Math.random() * 10) - 5);
s.transit({x: rh,y: rv}, 50, randomTran.bind(this, ++flag))
};
};
randomTran();
s.transit({x: 0,y: 0});
我试着让元素摇晃几秒钟,然后回到原来的位置。但它并没有像我预期的那样工作,问题出在回调函数上。根据这个问题:如果jQuery函数在其完成回调中调用自己,这对堆栈来说是递归的危险吗?,看起来,当回调仍在循环时,回调函数之后的代码也在执行。那么,除了设置超时之外,如何实现我的目标呢?我在哪里可以找到关于这种机制的更详细的解释?
你的fiddle按预期工作,动画被排队(如果.transit()
被多次重复调用,它们甚至会被排队,因为插件使用jQuery的内部动画队列)。唯一的问题是,对于一个高达5像素的动画来说,50毫秒太快了。我增加了时间,并在你小提琴的这次修订中打印了计数器。
看起来,当回调仍在循环时,回调函数之后的代码也在执行。
没有"循环回调"。回调被传递给函数,该函数在之前被return
调用,并且调用.transit()
的代码继续(在您的情况下,它是if的闭合}
大括号、randomTran()
调用的结束和s.transit({x: 0,y: 0});
初始化
一旦该代码完成执行,就可以异步执行其他代码。存储在某个地方的回调现在——将来,在transit()
调用后50ms——正在被调用;启动另一个转换,安排另一个回调,然后结束。
您的randomTran函数中没有回调,因此它异步运行。这意味着randomtran()在s.transit({x:0,y:0})之后启动;执行。
您可以运行s.transit({x:0,y:0});在randomTran的回调中,让它在休息后执行,如下所示:
var s = $('#shake');
var randomTran = function (flag,callback) {
flag = flag || 0;
if (flag < 6) {
var rh = Math.floor((Math.random() * 10) - 5),
rv = Math.floor((Math.random() * 10) - 5);
s.transit({x: rh,y: rv}, 50, randomTran.bind(this, ++flag))
}else{
callback();
}
};
randomTran(0,function(){ //0 is added because randomTran expects flag as first param
s.transit({x: 0,y: 0}); //this will be executed after randomtran calls back, eg when flag=6
});
但是。。。恐怕你把事情搞得太复杂了,我真的不确定你想实现什么。