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

One Div animation after another using deferred object

本文关键字:一个 延迟 对象 Div 动画      更新时间:2023-09-26

使用 deferred object 在上一个 Div 动画完成后对 Div 进行动画处理。这个简单的方法适用于两个函数f1f2,但是当我介绍f3时它失败了。

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

JSFiddle: https://jsfiddle.net/j0bgzjvd/

var deferred = $.Deferred();
function animationAgent(element, prevElement) {
  $(prevElement).promise().done( function () {
    return $(element).css("display", "block").animate({width:360},2000, "linear")
  });
}
function f1() {
  animationAgent("#div1"); 
} 
function f2() {
  animationAgent("#div2", "#div1"); 
} 
function f3() {
  animationAgent("#div3", "#div2"); 
}
deferred.resolve();
deferred.done( [ f1, f2, f3 ] );
div {
  width: 200px; 
  height: 200px; 
  background-color: red; 
  margin-bottom: 10px; 
  display: none;  
}
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>

你会发现

它更简单:

  • 使animationAgent()变成一个简单的、返回承诺的 worker 函数,它只知道它动画化的元素,而不知道它的使用顺序(即省略 prevElement ),
  • 安排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());

演示

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

下面是淡出的示例:https://jsfiddle.net/0r7e2wco/

fadeOutInTurn([
    $("#div1"),
    $("#div2"),
    $("#div3"),
    $("#div4"),
]);
//Fades out elements one after another
function fadeOutInTurn(elements) {
    var x = 0;
    function animate() {
        $(elements[x]).fadeOut(3000, function() {
            if(x < elements.length - 1) {
                x++;
                animate();
            }
        });
    }
    animate();
}

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

工作示例小提琴

我想你希望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]);