Javascript 使用延迟对象的一个又一个Div动画

Javascript 使用延迟对象的一个又一个Div动画,javascript,jquery,jquery-deferred,deferred,Javascript,Jquery,Jquery Deferred,Deferred,使用延迟对象在上一个Div动画完成后设置Div动画。这个简单的方法适用于两个函数f1和f2,但是当我引入f3时,它失败了 有没有更好的方法可以使用延迟对象实现这一点 JSFiddle: var deferred=$.deferred(); 函数animationAgent(元素,prevElement){ $(prevElement).promise().done(函数(){ return$(element).css(“display”,“block”).animate({width:360}

使用
延迟对象
在上一个Div动画完成后设置Div动画。这个简单的方法适用于两个函数
f1
f2
,但是当我引入
f3
时,它失败了


有没有更好的方法可以使用延迟对象实现这一点

JSFiddle:

var deferred=$.deferred();
函数animationAgent(元素,prevElement){
$(prevElement).promise().done(函数(){
return$(element).css(“display”,“block”).animate({width:360},2000,“linear”)
});
}
函数f1(){
动画师(“#div1”);
} 
函数f2(){
animationAgent(“div2”、“div1”);
} 
函数f3(){
animationAgent(“div3”、“div2”);
}
延迟。解决();
延期完成([f1、f2、f3])
div{
宽度:200px;
高度:200px;
背景色:红色;
边缘底部:10px;
显示:无;
}

有没有想过在动画函数中使用回调

下面是一个淡出的示例:

fadeouturn([
$(“第1分部”),
$(“第2分部”),
$(“第3分部”),
$(“第4分部”),
]);
//一个接一个地淡出元素
功能淡出(元素){
var x=0;
函数animate(){
$(元素[x])。淡出(3000,函数(){
if(x
您会发现:

  • 使
    animationAgent()
    成为一个简单的、承诺返回的辅助函数,该函数只知道它设置动画的元素,而不知道要使用它的顺序(即省略
    preveElement
  • 安排函数
    f1()
    f2()
    f3()
    ,以返回由
    animationAgent()返回的承诺
然后,您就有了构建可靠动画序列的基础

function animationAgent(element) {
    return $(element).css("display", "block").animate({width:360}, 2000, "linear").promise();
}
function f1() {
    return animationAgent("#div1"); 
} 
function f2() {
    return animationAgent("#div2"); 
} 
function f3() {
    return animationAgent("#div3"); 
}

f1().then(f2).then(f3);

或者,从函数引用数组机械地构造.then链:

function animationAgent(element) {
    return $(element).css("display", "block").animate({width:360}, 2000, "linear").promise();
}
function f1() {
    return animationAgent("#div1"); 
} 
function f2() {
    return animationAgent("#div2"); 
} 
function f3() {
    return animationAgent("#div3"); 
}

[f1, f2, f3].reduce(function(promise, fn) {
    return promise.then(function() {
        return fn();
    });
}, $.when());

或者,由于这三个动画是相同的,您可以通过从元素选择器数组构造.then链并直接调用
animationAgent()
来避免对单个函数的需要:

function animationAgent(element) {
    return $(element).css("display", "block").animate({width:360}, 2000, "linear").promise();
}

['#div1', '#div2', '#div3'].reduce(function(promise, selector) {
    return promise.then(function() {
        return animationAgent(selector);
    });
}, $.when());

不确定,但我想这就是你想要的

工作示例

我想你希望,
deferred.done()
将一个接一个地执行
f1、f2、f3
,它能很好地执行。但在调用下一个函数之前,它不会等待在这些函数中调用的动画终止

尝试使用
console.log()
在控制台上记录函数调用,您就会知道

以下是更新的javascript代码-

var deferred = $.Deferred();
var lock = 1;

function animationAgent(element, id, prevElement) {
  var interval;
  var flag = 0;
  if (id != lock) {
    interval = setInterval(function() {
      if (id == lock) {
        clearInterval(interval);
        animationAgent(element, id, prevElement);
      }
    }, 1000);
  }else{
    $(prevElement).promise().done(function() {
      lock++;
      return $(element).css("display", "block").animate({
        width: 360
      }, 2000, "linear");
    });
  }
}

function f1() {
  return animationAgent("#div1", 1);
}

function f2() {
  return animationAgent("#div2", 2, "#div1");
}

function f3() {
  return animationAgent("#div3", 3, "#div2");
}

deferred.resolve();
deferred.done([f1, f2, f3]);

您可以添加一个有此问题的代码段或bin吗?
控制台中的任何错误
?请参阅文章中更新的JSFIDLE。控制台中不存在任何错误。我想让div一个接一个地和谐地进行动画制作,但是你可以看到函数3在动画序列中造成了干扰。取出f3可以让f1和f2按顺序设置动画-@MoshFeuCheck out下面的答案可能会有所帮助@jcoulston2“有没有更好的方法可以实现这一点?”我假设他想知道一个又一个动画元素的更好方法。如果他想使用不同的对象,他应该使用notify()和progress()而不是resolve()和done(),通过这种方式,可以无限次地使用不同的对象^^^,但我不明白为什么会有人使用不同的模式依次为某些元素设置动画…感谢您的回复。是的,更具体地说是延迟对象,我的逻辑是使用promise方法来允许函数序列一个接一个地启动。原因是,这个动画是一个更复杂的点击阶段过程的一部分,我想尝试一下这个方法,以针对特定条件@seahorspip提供一个优雅的解决方案
var deferred = $.Deferred();
var lock = 1;

function animationAgent(element, id, prevElement) {
  var interval;
  var flag = 0;
  if (id != lock) {
    interval = setInterval(function() {
      if (id == lock) {
        clearInterval(interval);
        animationAgent(element, id, prevElement);
      }
    }, 1000);
  }else{
    $(prevElement).promise().done(function() {
      lock++;
      return $(element).css("display", "block").animate({
        width: 360
      }, 2000, "linear");
    });
  }
}

function f1() {
  return animationAgent("#div1", 1);
}

function f2() {
  return animationAgent("#div2", 2, "#div1");
}

function f3() {
  return animationAgent("#div3", 3, "#div2");
}

deferred.resolve();
deferred.done([f1, f2, f3]);