也许这个问题是重复的。我发现了很多类似的问题,但没有人能真正解决我的问题。这是我的任务:
function animate(){
$ul.each(function(){
$(this).find('li').each(function(){
//animate block
$(this).animate({top:'-100%'},100,function(){
$(this).css({top:'100%'});
});
//endblock
});
});
}
正如您所知,'动画块'函数将同时运行。我希望他们按顺序运行。我怎样才能做到这一点?
我已经阅读了jQuery' deferred',' Q'关联文章,但仍然令人困惑。
抱歉我的英文。
---------此外------
如果我想多次运行动画功能,我该怎么办?
答案 0 :(得分:1)
使用queue()
函数检查此解决方案。
此功能等待动画完成,然后执行它的内容。
var anim = function(i) {
$('.test').eq(i).animate({'top':'20px'}, 350).queue(function() {
i++;
anim(i);
$(this).dequeue();
});
}
anim(0);
.test {
width:50px;
height:50px;
float: left;
margin-right:10px;
background-color:green;
position:relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="test">test</div>
<div class="test">test</div>
<div class="test">test</div>
<div class="test">test</div>
<div class="test">test</div>
答案 1 :(得分:0)
这样的事情应该有效:
var last_deferred = $.Deferred();
last_deferred.resolve();
$ul.each(function(){
$(this).find('li').each(function(){
var deferred = $.Deferred(),
$that = $(this);
last_deferred.then(function() {
$that.animate({top:'-100%'},100,function(){
$(this).css({top:'100%'});
deferred.resolve();
});
});
last_deferred = deferred;
});
});
说明:我在这里使用了延迟对象.then
和.resolve
的两个重要功能。当您致电.resolve();
时,延迟对象将通过.then
触发分配给它的所有处理程序。所以会发生的事情是我首先定义&#34; dummy&#34;推迟我立即解决。如果解析了延迟对象,则通过.then
添加处理程序将自动使其运行。那么会发生什么呢
last_deferred
已定义并已解决deferred
.then
处理程序添加到last_deferred
.then
处理程序被触发,在执行某些操作后,它会解析deferred
(从而在.then
上触发deferred
)last_deferred
被重新定义为deferred
所以这是一种异步循环(因为.animate
是异步操作)。在每个步骤中,您说&#34;当前一个deferred
被解析时,告诉它解决下一个&#34;。
答案 2 :(得分:0)
如果你想避免jQuery的笨拙.queue()
/ .dequeue()
,那么你可以从<li>
元素的jQuery集合构建一个promise链。
function animate($ul) {
var p = $.when(); //resolved starter promise
$("li", $ul).each(function(i, li) {
p = p.then(function() {
return $(li).animate({ top:'-100%' }, 100, function() {
return $(li).css({ top:'100%' });
}).promise();
});
});
return p;
}
随着链的稳定,动画将按顺序发生。
更优雅的是,您可以将jQuery扩展为.reduce()
方法,从Array.prototype
采用。
jQuery.fn.reduce = Array.prototype.reduce;
然后,通过在jQuery集合上调用.reduce()
来构建所需的promise链。
function animate($ul) {
return $("li", $ul).reduce(function(p, li) {//wow, jQuery has a .reduce() method!
return p.then(function() {
//Here, perform the required animation and return a promise of its completion.
return $(li).animate({top:'-100%'}, 100, function() {
$(li).css({top:'100%'});
}).promise();
});
}, $.when());//Resolved starter promise, ie p in the first iteration of .reduce() .
}
这种模式非常值得学习,因为它有很多应用程序。
在这两个示例中,最外面的return
允许您在调用.then()
的地方链animate()
:
animate($("ul")).then(function() {
//do something when all the <li> animations have completed.
});
答案 3 :(得分:0)
尝试使用.queue()
,$.map()
,.delay()
;在window.innerHeight
代替100
,px
单位代替%
单位;在.animate()
回拨
.animate
代替.css
complete
&#13;
var ul = $("ul");
ul.queue("_fx", $.map(ul.find("li"), function(el, i) {
return function(next) {
return $(el).animate({
top: "-" + window.innerHeight / 10 + "px"
}, 100, function() {
$(this).delay(100).animate({
top: window.innerHeight - $(this).height() * 1.5 + "px"
}, 100, next);
})
};
})).dequeue("_fx");
&#13;
body {
height: 200px;
}
ul li {
top: 150px;
position: relative;
width: 50px;
height: 50px;
background: red;
padding 8px;
display: inline-block;
}
&#13;