【问题标题】:Javascript wait for one animation to finish before the next one beginsJavascript 在下一个动画开始之前等待一个动画完成
【发布时间】:2014-01-24 11:47:29
【问题描述】:

我有一个 Javascript 函数(不是 jQuery),可以为盒子的打开或关闭设置动画。问题是我关闭了框,运行了一些更改内容的代码,然后重新打开它。

现在的“问题”是其余代码太快了,因此它甚至无法关闭,更不用说重新打开了。我可以让动画不允许在内部再次运行,除非最后一个完成,但如果我说要在两个不同的对象上运行两次,这会限制它。

那么防止这种情况的最佳方法是什么?我的想法可能是在运行动画之前表示要等待的超时,但这似乎很hacky,我不确定是否有更好的解决方案?

谢谢。

function animate(boxID, step, limit, speed){
    // Add timeout property to animate function/object if it doesn't exist already
    if(animate.timeout == undefined) animate.timeout = 0;

    // Clear the current timeout
    clearTimeout(animate.timeout);

    // Initialize box and current box height
    var box = document.getElementById(boxID);
    var h   = box.clientHeight;

    // Check if we want the step needs to be changed to pos/neg based on which direction is wanted to be going
    if(h < limit && step < 0 || // Positive
       h > limit && step > 0){  // Negative
        step *= -1;
    }


    // If the step is positive, then we need to be below the limit, or if negative, then greater than the limit
    if((step > 0 && h <= limit - step) || (step < 0 && h >= limit - step)){
        // Set new height
        box.style.height = h + step + "px";

        // Start new timeout
        animate.timeout = setTimeout(function(){ animate(boxID, step, limit, speed, 1); }, speed);
    }
    else{
        box.style.height = limit + "px"; // Set to the exact height
    }
}

【问题讨论】:

  • 请分享您的代码。我想你错过了一些回调和 requestAnimationFrame。
  • @FilipGórny 添加到原帖。
  • 考虑使用 HTML5 requestAnimationFrame 代替 setTimeout paulirish.com/2011/requestanimationframe-for-smart-animating
  • @MarkKnol 看起来我仍然有同样的问题,尽管这可能对另一个项目有好处。我正在运行的动画足够快,不用担心内存部分。

标签: javascript animation wait


【解决方案1】:

您可以通过回调实现此目的。你的animate 函数有一个加号参数,一个在动画准备好时调用的函数:

function animate(boxID, step, limit, speed, onReady){

动画完成后,你调用它:

else{
    box.style.height = limit + "px"; // Set to the exact height
    if (onReady) { onReady(); }
}

您还想将回调转发到超时调用:

setTimeout(function(){ animate(boxID, step, limit, speed, 1, onReady); }, speed);

因此,您可以像这样为多个框调用该函数:

animate(box1_id, close_step, close_limit, close_speed, function () {
    // now box1 is closed, put something in. then:
    animate(box1_id, open_step, open_limit, open_speed, null);
});
// then the same for box2, etc…

这样box1和box2会同时关闭,等东西放进去后才会重新打开。

此外,您不能将计时器存储在函数上,因为现在它在多个盒子上运行。所以你可以把它存放在盒子上,或者一个单独的地方。例如,在函数之外创建一个对象并将所有盒子的计时器放入其中:

var timeouts = {};
timeouts[box1_id] = setTimeout(…);

【讨论】:

  • 听起来应该可以。现在,有没有办法使用 new 或其他东西来将超时 ID 保留为函数的一部分?喜欢new animation(...)
猜你喜欢
  • 2014-12-01
  • 1970-01-01
  • 2016-11-26
  • 2016-11-29
  • 1970-01-01
  • 2012-12-30
  • 2019-07-26
  • 2021-05-25
  • 2023-03-17
相关资源
最近更新 更多