2016-11-08 54 views
1

编辑: 这里接受的答案:How to get jQuery to wait until an effect is finished?不能解决我的问题,因为回调函数是在jQuery UI效果完成之前执行的。在这个线程上还有另一个答案,它指向promise(),但这只是答案的一部分,并且缺少许多信息。如何等待,直到一个循环的jQuery效果完成之前执行功能

我想等到一个jQuery效果循环完全完成动画,直到执行回调函数。

但是,似乎回调函数在最后一个jquery效果开始后立即执行,但不会等待动画结束。

我想知道如何等待元素被隐藏使用jquery拖放效果为循环中的所有元素,并且只有在元素已完全隐藏回调函数运行后。

<html> 
<head> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> 
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css"> 
</head> 
<body> 
    <button id="execute-button">Execute</button> 
    <div id="messagebox"></div> 
    <div id="1" style="background-color:blue;display:none;height:33%;width:100%;"></div> 
    <div id="2" style="background-color:green;display:none;height:33%;width:100%;"></div> 
    <div id="3" style="background-color:red;display:none;height:34%;width:100%;"></div> 
    <div id="4" style="background-color:brown;height:33%;width:100%;"></div> 
    <div id="5" style="background-color:black;height:33%;width:100%;"></div> 
    <div id="6" style="background-color:gray;height:34%;width:100%;"></div> 
    <script> 
     $(document).ready(function(){ 

      function hideElements(callback){ 
       //hide elements 
       var hideDivs = ["#4","#5","#6"]; 
       for(i = 0; i < hideDivs.length; i++){ 
        //alert("hiding..."); 
        $(""+hideDivs[i]).hide("drop",{direction:"left"},5000); 
        //alert(divs[i]); 
       } 
       callback(); 
      }; 

      function showElements(){ 
       //show elements 
       var showDivs = ["#1","#2","#3"]; 
       //alert(JSON.stringify(divs)); 
       for(i = 0; i < showDivs.length; i++){ 
        //alert("showing..."); 
        $(""+showDivs[i]).show("drop",{direction:"right"},1000); 
        //alert(divs[i]); 
       } 
      } 


      hideElements(showElements()); 

     }); 


     $(document).on("click","#execute-button", function(){ 
      //$("#messagebox").html("test"); 
      $("#1").show("#1"); 
     }); 
    </script> 
</body> 
</html> 
+0

需要使用回调,当隐藏事件结束时回应http://api.jquery.com/hide/ – garryp

+0

@ jfriend00提供的副本显示了如何等待一个效果完成,而不是多个,这是什么问题是问,如果我没有弄错。 –

+0

@MikeMcCaughan - 对143个upvotes的答案在多个对象中工作得很好。 '$(selector).promise()。done()'捕获在该选择器匹配的所有对象中运行的所有动画。 – jfriend00

回答

3

在jQuery中,如果你在一个jQuery集合使用.promise(),它将返回时,集合中的所有元素都完成了他们的动画解决的承诺。因此,您应该能够在每个元素上触发动画,然后在集合上执行.promise(),并在该承诺结算时,您可以执行其他动画。

这里的工作片断例如:

// returns a promise that resolves when all animations started here are done 
 
function showHide() { 
 
    var items = $("#4, #5, #6"); 
 
    return items.slideUp(2000).promise().then(function() { 
 
     // this runs when all animations in the items collection are done 
 
     return items.slideDown(2000).promise(); 
 
    }); 
 
} 
 

 
$("#go").click(function() { 
 
    showHide().then(function() { 
 
     console.log("animation done"); 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 

 

 
<div> 
 
<button id="go">Run</button> 
 
</div> 
 

 
<div style="height: 300px;"> 
 
    <div id="4" style="background-color:brown;height:33%;width:100%;"></div> 
 
    <div id="5" style="background-color:black;height:33%;width:100%;"></div> 
 
    <div id="6" style="background-color:gray;height:34%;width:100%;"></div> 
 
</div>


当然,如果动画的所有第一组具有相同的时间,你可以使用jQuery的动画链接(其中动画对于给定的对象进入队列并且随后的动画等待在开始之前完成之前的动画):

// returns a promise that resolves when all animations started here are done 
function showHide() { 
    return $("#4, #5, #6").slideUp(2000).slideDown(2000).promise(); 
} 
+0

你也可以做'items.slideUp(2000).slideDown(2000).promise()。然后(function(){...})作为动画链无论如何 – Bergi

+0

@Bergi - 是的,但这个问题的更一般的部分是如何知道何时完成一组动画(所有这些动画在一般情况下可能都没有相同的持续时间),然后您可以开始第二组动画。所以我认为这会教导更有用的东西,而不仅仅是链接动画。为了完整性,我会添加一些关于动画链接的信息。 – jfriend00

相关问题