我怎样才能运行很多个函数依次执行?
How can I run a lot of functions in sequence?
也许这个问题是重复的。我发现了很多类似的问题,但没有人能真正解决我的问题。这是我的任务:
function animate(){
$ul.each(function(){
$(this).find('li').each(function(){
//animate block
$(this).animate({top:'-100%'},100,function(){
$(this).css({top:'100%'});
});
//endblock
});
});
}
如您所知,'animate block' 个函数将同时 运行。我希望它们按顺序 运行。我怎样才能做到这一点?
我已经阅读了 jQuery 'deferred'、'Q' 相关文章,但仍然感到困惑。
对不起我的英语。
---------加法-----
如果我想运行动画函数多次,我应该怎么做?
像这样的东西应该可以工作:
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
分配给它的所有处理程序。所以发生的事情是我首先定义 "dummy" deferred 我立即解决。如果延迟对象已解析,则通过 .then
添加处理程序将自动使其成为 运行。那么会发生什么
last_deferred
已定义并解决
- 临时
deferred
已创建
- 将
.then
处理程序添加到 last_deferred
.then
处理程序被触发,并在它完成一些事情后解析 deferred
(因此在 deferred
上触发 .then
)
last_deferred
重新定义为 deferred
- 回到2.
所以这是一种异步循环(因为 .animate
是一个异步操作)。在每一步你说 "when previous deferred
is resolved tell it to resolve the next one".
使用 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>
如果你想避免 jQuery 的尴尬 .queue()
/.dequeue()
,那么你可以从 [=16] 的 jQuery 集合构建一个承诺链=] 元素。
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()
来构建所需的承诺链。
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
允许您在调用 animate()
的任何地方链接 .then()
:
animate($("ul")).then(function() {
//do something when all the <li> animations have completed.
});
尝试利用 .queue()
, $.map()
, .delay()
;将 window.innerHeight
替换为 100
,将 px
单元替换为 .animate()
处的 %
单元;在 complete
回调
处用 .animate
替换 .css
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");
body {
height: 200px;
}
ul li {
top: 150px;
position: relative;
width: 50px;
height: 50px;
background: red;
padding 8px;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<ul>
<li>a
</li>
<li>b
</li>
<li>c
</li>
<li>d
</li>
<li>e
</li>
<li>f
</li>
<li>g
</li>
</ul>
也许这个问题是重复的。我发现了很多类似的问题,但没有人能真正解决我的问题。这是我的任务:
function animate(){
$ul.each(function(){
$(this).find('li').each(function(){
//animate block
$(this).animate({top:'-100%'},100,function(){
$(this).css({top:'100%'});
});
//endblock
});
});
}
如您所知,'animate block' 个函数将同时 运行。我希望它们按顺序 运行。我怎样才能做到这一点?
我已经阅读了 jQuery 'deferred'、'Q' 相关文章,但仍然感到困惑。
对不起我的英语。
---------加法-----
如果我想运行动画函数多次,我应该怎么做?
像这样的东西应该可以工作:
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
分配给它的所有处理程序。所以发生的事情是我首先定义 "dummy" deferred 我立即解决。如果延迟对象已解析,则通过 .then
添加处理程序将自动使其成为 运行。那么会发生什么
last_deferred
已定义并解决- 临时
deferred
已创建 - 将
.then
处理程序添加到last_deferred
.then
处理程序被触发,并在它完成一些事情后解析deferred
(因此在deferred
上触发.then
)last_deferred
重新定义为deferred
- 回到2.
所以这是一种异步循环(因为 .animate
是一个异步操作)。在每一步你说 "when previous deferred
is resolved tell it to resolve the next one".
使用 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>
如果你想避免 jQuery 的尴尬 .queue()
/.dequeue()
,那么你可以从 [=16] 的 jQuery 集合构建一个承诺链=] 元素。
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()
来构建所需的承诺链。
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
允许您在调用 animate()
的任何地方链接 .then()
:
animate($("ul")).then(function() {
//do something when all the <li> animations have completed.
});
尝试利用 .queue()
, $.map()
, .delay()
;将 window.innerHeight
替换为 100
,将 px
单元替换为 .animate()
处的 %
单元;在 complete
回调
.animate
替换 .css
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");
body {
height: 200px;
}
ul li {
top: 150px;
position: relative;
width: 50px;
height: 50px;
background: red;
padding 8px;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<ul>
<li>a
</li>
<li>b
</li>
<li>c
</li>
<li>d
</li>
<li>e
</li>
<li>f
</li>
<li>g
</li>
</ul>