【问题标题】:JS/jQuery: Wait for function with animations to be finishedJS/jQuery:等待带有动画的函数完成
【发布时间】:2014-08-19 12:31:28
【问题描述】:

目前,当用户单击一个按钮时,会执行几个 javascript 函数。因为每个函数都会在站点上执行一些动画(更多信息可以在第二条评论中找到),所以我必须一个接一个地执行它们,所以 jQuery 不会搞砸,因为它在一个甚至没有的元素上启动了一个动画已加载/显示。

我当前的解决方案是使用setTimeout 调用每个函数,然后调用前一个函数,如下所示:

window.setTimeout(functionA,250);
window.setTimeout(functionB,500);

这在 Chrome 中效果很好,但在 Firefox 中有时执行速度仍然太快。因此,我希望通过告诉 Javascript 仅在前一个函数完全完成时才执行下一个函数来解决此解决方法。

我已经阅读了有关添加回调的信息 - 但我有很多函数要调用。我真的必须为每个函数添加回调来实现我想要的吗?

非常感谢。

【问题讨论】:

  • 请分享你的动画功能..
  • 所有函数的目标:通过 AJAX 加载一些信息,将它们添加到下拉菜单(.html()),对下拉菜单进行排序,最后选择特定选项(.prop())。 4 个步骤,4 个功能。如果在执行下一个功能时任何功能尚未完成,那么它 - 显然 - 将无法正常工作,因为缺少最后一步。

标签: javascript jquery


【解决方案1】:

如果您使用 jQuery 动画,请查看 jQuery.Deferred。它是所有动画函数的结果,如fadeIn()、slideDown()、animate()。

你可以像这样组合几个延迟:

var anim1 = $('.sth').animate({left:100});
var anim2 = $('.sth2').fadeOut();
var anim3 = $('.sth4').slideDown();
$.when(anim1, anim2, anim3).then(function(){
    console.log('Animations are ready');
})

【讨论】:

  • 我已经在作者删除的答案的评论中说过这一点。我没有使用真正的“动画”,我只是使用html() 插入数据并使用prop() 选择一个下拉版本 - 我在原始问题的第一条评论中提到了所有必要的步骤。
  • 不是动画也没关系,Deferred 对任何异步动作都有用。值得关注:joseoncode.com/2011/09/26/…,如果您想要更具体的内容,请发布您的所有代码,以便我们进行编辑。
  • 正如 Ella Ryan 所说:Deferred 将涵盖这种情况。 pastebin.com/S8GfRK5y
【解决方案2】:

你为什么不直接使用这样的东西:

$(document).ready(function(){
  $("button").click(function(){
    $.ajax({url:"demo_test.txt",success:function(result){//if your ajax request success

      $("#div1").html(result); // add the result into the HTML

      Sort();//do sorting

      SelectOption();//select the option
    }});
  });
});

【讨论】:

  • 在此示例中,有时会选择错误的选项,因为列表尚未完全排序。
  • 你确定是因为排序没有完成吗?因为据我所知SelectOption 将在Sort 完成后执行..
  • 绝对。这就是为什么我将setTimeout 添加到每个函数中,这样它就不会像以前那样混乱了。但这只是一个基本的例子。有时我必须在 SelectOption 之后执行另一个 AJAX 请求,该请求从下拉列表中读取所选选项 - 无需等待,它要么读取 no 要么读取错误的选定版本。
【解决方案3】:

您可以尝试使用$.when()$.then()。我不知道您的代码到底是什么,但使用您的示例,如下所示:

$.when(functionA).then(functionB);

这将确保 A 在 B 之前完成,而不是使用任意超时。

编辑:实际上考虑一下,这可能对您不起作用。我建议您研究一下 jQuery 中的 Deferred 和 Promise,它可以帮助您管理异步操作而无需所有回调。

【讨论】:

    【解决方案4】:

    您必须添加回调,因为 javascript 计时器不可靠。

    我推荐阅读以下文章:How JavaScript Timers Work

    【讨论】:

      【解决方案5】:

      我经常遇到这个问题。如果有更好的方法来做到这一点,我还没有找到它,因为 JS 想要尽可能快地运行,所以它会尝试“同时”尽可能多地执行。

      你唯一能做的就是让函数返回一个必须在下一个函数中使用的值。

      所以...

      // This should complete first
      function a(target){
          $(target).css('color','black');
          var return_this = a + 1;
          return return_this;
      }
      
      // This should complete second
      function b(target,a){
          var return_this = a + 1;
          $(target).css('color','white');
          return return_this;
      }
      
      // This should run third
      function c(target,b){
          var return_this = b + 1;
          $(target).css('color','grey');
          return return_this;
      }
      
      
      $('a').click(){
          var a = a(this);
          var b = b(this,a);
          var c = c(this,b);
          $(this).attr('data-temp',c);
      }
      

      这是理论上的,因为我几个月前就研究过这个问题,现在无法访问它。您可能需要稍微尝试一下才能使其正常工作。

      【讨论】:

        猜你喜欢
        • 2014-01-21
        • 2012-08-23
        • 1970-01-01
        • 2017-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多