2016-11-08 51 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

相關問題