等到有animation的函数结束后再运行另一个函数
我遇到了一个正常( 非Ajax )函数的问题,每个函数都涉及大量的animation 。 目前我只是有一个setTimeout
function之间,但这并不完美,因为没有浏览器/电脑是相同的。
附加说明:他们都有单独的animation/等相撞。
我不能简单地把一个放在另一个的callback函数中
// multiple dom animations / etc FunctionOne(); // What I -was- doing to wait till running the next function filled // with animations, etc setTimeout(function () { FunctionTwo(); // other dom animations (some triggering on previous ones) }, 1000);
反正在js / jQuery中有:
// Pseudo-code -do FunctionOne() -when finished :: run -> FunctionTwo()
我知道$.when()
& $.done()
,但这些是为AJAX …
- 我更新的解决scheme
jQuery有一个暴露的variables(出于某种原因,没有在jQuery文档中的任何地方列出),名为$ .timers,其中包含当前正在发生的animation数组。
function animationsTest (callback) { // Test if ANY/ALL page animations are currently active var testAnimationInterval = setInterval(function () { if (! $.timers.length) { // any page animations finished clearInterval(testAnimationInterval); callback(); } }, 25); };
基本用途:
// run some function with animations etc functionWithAnimations(); animationsTest(function () { // <-- this will run once all the above animations are finished // your callback (things to do after all animations are done) runNextAnimations(); });
你可以使用jQuery的$.Deferred
var FunctionOne = function () { // create a deferred object var r = $.Deferred(); // do whatever you want (eg ajax/animations other asyc tasks) setTimeout(function () { // and call `resolve` on the deferred object, once you're done r.resolve(); }, 2500); // return the deferred object return r; }; // define FunctionTwo as needed var FunctionTwo = function () { console.log('FunctionTwo'); }; // call FunctionOne and use the `done` method // with `FunctionTwo` as it's parameter FunctionOne().done(FunctionTwo);
你也可以打包多个延期:
var FunctionOne = function () { var a = $.Deferred(), b = $.Deferred(); // some fake asyc task setTimeout(function () { console.log('a done'); a.resolve(); }, Math.random() * 4000); // some other fake asyc task setTimeout(function () { console.log('b done'); b.resolve(); }, Math.random() * 4000); return $.Deferred(function (def) { $.when(a, b).done(function () { def.resolve(); }); }); };
将以下内容添加到第一个函数的末尾
return $.Deferred().resolve();
调用这样的function
functionOne().done(functionTwo);
随着Yoshi的回答,我发现了另一个非常简单的(callbacktypes)animation解决scheme。
jQuery有一个暴露的variables(出于某种原因,没有在jQuery文档中的任何地方列出),名为$ .timers ,其中包含当前正在发生的animation数组。
function animationsTest (callback) { // Test if ANY/ALL page animations are currently active var testAnimationInterval = setInterval(function () { if (! $.timers.length) { // any page animations finished clearInterval(testAnimationInterval); callback(); } }, 25); };
基本用途:
functionOne(); // one with animations animationsTest(functionTwo);
希望这可以帮助一些人!
这是你的意思吗: http : //jsfiddle.net/LF75a/
你将有一个函数触发下一个函数等,即添加另一个函数调用,然后添加你的functionONe
在它的底部。
请让我知道如果我错过了什么,希望它适合原因:)
或者 : 在前一个function完成后调用一个函数
码:
function hulk() { // do some stuff... } function simpsons() { // do some stuff... hulk(); } function thor() { // do some stuff... simpsons(); }
这个答案使用了ECMAScript 6
标准的JavaScript特性promises
。 如果您的目标平台不支持promises
,请使用PromiseJs进行填充 。
您可以使用jQuery在animation调用中使用.promise()
创build的Deferred
对象。 将这些Deferreds
包装到ES6 Promise中会比使用定时器产生更清晰的代码。
您也可以直接使用Deferreds
,但是由于它们不遵循Promise / A +规范,所以通常不鼓励。
结果代码如下所示:
var p1 = Promise.resolve($('#Content').animate({ opacity: 0.5 }, { duration: 500, queue: false }).promise()); var p2 = Promise.resolve($('#Content').animate({ marginLeft: "-100px" }, { duration: 2000, queue: false }).promise()); Promise.all([p1, p2]).then(function () { return $('#Content').animate({ width: 0 }, { duration: 500, queue: false }).promise(); });
请注意, Promise.all()
中的函数返回promise。 这是魔术发生的地方。 如果在一次调用中返回一个承诺,那么下一次调用将等待该承诺在执行之前被解决。
jQuery为每个元素使用一个animation队列。 所以同一元素上的animation是同步执行的。 在这种情况下,你根本不必使用promise。
我禁用了jQueryanimation队列来演示如何使用promise。
Promise.all()
接受一组promise,并创build一个新的Promise
,完成数组中的所有promise。
Promise.race()
也承诺了一系列的承诺,但是当第一个Promise
完成时,就结束了。
ECMAScript 6 UPDATE
这使用了一个名为Promises的JavaScript新特性
functionOne(),然后(functionTwo)。
你可以通过callback函数来完成。
$('a.button').click(function(){ if (condition == 'true'){ function1(someVariable, function() { function2(someOtherVariable); }); } else { doThis(someVariable); } });
函数function1(param,callback){… do stuff callback(); }
这是一个解决n个调用(recursion函数)。 https://jsfiddle.net/mathew11/5f3mu0f4/7/
function myFunction(array){ var r = $.Deferred(); if(array.length == 0){ r.resolve(); return r; } var element = array.shift(); // async task timer = setTimeout(function(){ $("a").text($("a").text()+ " " + element); var resolving = function(){ r.resolve(); } myFunction(array).done(resolving); }, 500); return r; } //Starting the function var myArray = ["Hi", "that's", "just", "a", "test"]; var alerting = function (){window.alert("finished!")}; myFunction(myArray).done(alerting);