从嵌套动画返回结果
Return a result from nested animation
我有一个用于操作单个字母的动画循环。它包装在计时器中以创建延迟偏移量。每个字母的动画效果比前一个字母晚 100 毫秒。我需要弄清楚如何判断完整动画何时完成,但由于使用的不同类型的嵌套,我遇到了一些麻烦。
我已经尝试了一些不同的事情,包括尝试从动画中返回一个值,然后是计时器,然后是 $.each 函数,但我确定这是关闭的。我也在想我也许能够使用 jQuery 的 animate 函数提供的承诺,但不确定如何实现这一点。这里的任何建议将不胜感激:]谢谢
这是我当前的代码:
var offset = 200;
//drop individual letters down out of view
function dropLetters($letters){
var len = $letters.length - 1;
$letters.each(function(i){
var $letter = $(this);
setTimeout(function(){
$letter.animate({ top: offset + 'px' }, 300, function(){
if( i >= len ){
return $(this).promise();
}
});
}, 100 * i );
});
}
编辑:对不起,我意识到我省略了偏移变量。我把它加回来 - 它只是设置为值 200。
另外,我意识到这个问题与另一个问题相似,但似乎也有所不同。这里提供的答案给出了其他问题中不存在的几种不同方法。
一种利用 、.promise()
$.when()
Function.prototype.apply()
、$.map()
、.delay()
的方法。请注意,将链接.apply()
替换为.promise()
,以便$.when()
将this
作为包含元素的 jQuery 对象返回,而不是在 .then()
处返回包含 jQuery 对象的数组
var offset = 100, duration = 300, delay = 100, curr = 0;
function dropLetters(elems) {
return $.fn.promise.apply(elems, $.map(elems, function(el) {
return $(el).delay(curr += delay).animate({top: offset + "px"}, duration)
}))
}
dropLetters($("button")).then(function() {
console.log("complete", this)
})
button {
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<button>
0
</button>
<button>
1
</button>
<button>
2
</button>
或者,使用 $.when()
、 .queue()
var offset = 100, duration = 300, delay = 100, curr = 0;
function dropLetters(elems) {
return $.when(elems.queue(function (next) {
$(this).delay(curr += delay).animate({top:offset + "px"}, duration, next())}))
}
dropLetters($("button")).then(function() {
console.log("complete", this)
})
button {
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<button>
0
</button>
<button>
1
</button>
<button>
2
</button>
您可以从每个setTimeout
调用中做出承诺,并且不需要自己跟踪所有异步操作是否已完成。
function dropLetters($letters){
var promises = [];
$letters.each(function(i){
var $letter = $(this);
promises.push(new Promise(function(resolve, reject) {
setTimeout(function(){
$letter.animate({ top: offset + 'px' }, 300, function(){
resolve();
});
}, 100 * i );
});
});
return Promise.all(promises);
}
请注意,您可能需要承诺填充材料 请参阅 http://caniuse.com/#feat=promises
与检查索引的现有答案相比,我的答案的好处之一是,如果您将动画更改为向后,则必须在两个地方修改代码。请参阅下面的版本,其中字母向后(和向前)飞出。
function dropLetters($letters, backwards) {
var promises = [];
$letters.each(function(i) {
var $letter = $(this);
promises.push(new Promise(function(resolve, reject) {
setTimeout(function() {
$letter.animate({
top: '-100px'
}, 300, function() {
resolve();
});
}, 100 * (backwards ? $letters.length - i : i));
}));
});
return Promise.all(promises);
}
dropLetters($('p')).then(function() {
alert('finished')
});
dropLetters($('span'), true).then(function() {
alert('finished')
});
p, span {
position: relative;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<p>A</p>
<hr style="clear: both"/>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
<span>B</span>
$.Deferred()
,.resolveWith()
function dropLetters($letters) {
var len = $letters.length - 1;
var dfd = $.Deferred();
$letters.each(function(i) {
var $letter = $(this);
setTimeout(function() {
$letter.animate({
top: offset + 'px'
}, 300, function() {
if (i >= len) {
dfd.resolveWith($(this));
}
});
}, 100 * i);
});
return dfd.promise()
}
正如他们所说,你可以使用 $。延期()'为了说明,我添加了一个基于给定代码的示例。;-)
//drop individual letters down out of view
function dropLetters($letters){
var deferred = jQuery.Deferred();
$letters.each(function(i,elem){
var $letter = $(elem);
var timer = setTimeout(function(){
$letter.animate({ top: $letter.offset().top-100 }, 300, function(f){
if(i+1>=$letters.length){// last letter was animated
deferred.resolve();
}
});
}, 300*i );
});
return deferred;
}
dropLetters($('p')).then(function(){alert('finished')});
p{
position:relative;
float:left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p>
- 是否可以将JXBrowser显示的JS确认对话框的结果返回到调用它的JS部分
- 将字符串结果返回到表单元格中的新行中
- 如何从批处理文件调用一个带有2个参数的java脚本函数,并将结果返回到环境变量
- 使用 JSON 和 ExtJS 将 MPDF 结果返回给浏览器
- 将信息结果返回到多个输入字段
- 如何将变量从javascript发送到php并将结果返回给JS
- 将 JavaScript 变量传递给 PHP,并将 PHP 结果返回给 JavaScript 变量
- 当没有结果返回 JavaScript 搜索时显示消息
- 加载相同的结果返回按钮
- 如果搜索框位于_SiteLayout页(在页眉 DIV 中),如何将搜索结果返回给用户
- MVC C#中的自定义操作结果返回特定视图
- 使用javascript/lodash对特定键的相同值进行分组,并对其进行计数,然后将结果返回到数组
- 如何使用javascript将循环结果返回到列中
- 结果返回为“未定义”
- 搜索未检测到结果返回-Selectize.js
- 调用一个打开活动并将活动结果返回给javascript的java函数
- 将PHP结果返回到原始html页面
- ASP.. NET MVC控制器结果返回到视图
- 如何通过AJAX传递值来更改SQL搜索查询并将结果返回给HTML ?
- Asp.net MVC或javascript将另一个页面的结果返回给方法