2016-11-08 3 views
1

Edit: Die akzeptierte Antwort hier: How to get jQuery to wait until an effect is finished? löst nicht mein Problem, weil die Callback-Funktion ausgeführt wird, bevor die jquery ui-Effekte abgeschlossen wurden. Es gibt auch eine andere Antwort auf diesen Thread, der sich auf promise() bezieht, aber dies ist nur ein Teil der Antwort und es fehlen viele Informationen.Warten, bis eine Schleife von Jquery-Effekten fertig ist, bevor die Funktion ausgeführt wird

Ich versuche zu warten, bis eine Schleife von Jquery-Effekten Animationen vollständig abgeschlossen hat, bis eine Callback-Funktion ausgeführt wird.

Es scheint jedoch, dass die Callback-Funktion unmittelbar nach dem Start des letzten Jquery-Effekts ausgeführt wird, aber nicht auf den Abschluss der Animationen wartet.

Ich frage mich, wie kann ich warten, dass die Elemente mit jquery Drop-Effekt für alle Elemente in der Schleife verborgen werden, und erst nachdem die Elemente vollständig ausgeblendet wurden, wird die Callback-Funktion ausgeführt.

<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

Notwendigkeit, Rückrufe zu verwenden, die reagieren, wenn das Ausblenden-Ereignis beendet wird http://api.jquery.com/hide/ – garryp

+0

@ jfriend00 Das gelieferte Duplikat zeigt, wie gewartet wird, bis ein einzelner Effekt beendet ist, nicht mehrere, was das ist Frage stellt sich, wenn ich mich nicht irre. –

+0

@MikeMcCaughan - Die Antwort in diesem dup mit 143 upvotes funktioniert gut für mehrere Objekte. '$ (selector) .promise(). done()' erfasst alle Animationen, die in allen Objekten ausgeführt werden, denen der Selektor entspricht. – jfriend00

Antwort

3

In jQuery, wenn Sie .promise() auf einer jQuery Sammlung verwenden, wird es ein Versprechen zurück, die aufgelöst wird, wenn alle Elemente in der Sammlung ihre Animation beendet haben. Also, Sie sollten in der Lage sein, nur die Animation auf jedes Element zu feuern, dann tun Sie .promise() auf die Sammlung und wenn dieses Versprechen verrechnet wird, können Sie dann die andere Animation tun.

Hier ist ein Arbeits Snippet Beispiel:

// 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>


Natürlich, wenn alle Ihre erste Gruppe von Animationen die gleiche Timing haben, können Sie einfach jQuery Animation verwenden Chaining (wo Animationen für ein gegebenes Objekt in eine Warteschlange gehen und eine nachfolgende Animation darauf warten, dass die vorherige vor dem Start ausgeführt wird):

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

Sie können auch 'items.slideUp (2000) .slideDown (2000) .promise(). Dann (function() {...})' als Animation Kette sowieso – Bergi

+0

@Bergi - Ja, aber der allgemeinere Teil dieser Frage ist, wie man weiß, wann eine Gruppe von Animationen fertig ist (die im allgemeinen Fall möglicherweise nicht alle die gleiche Dauer haben), um dann eine zweite Gruppe von Animationen zu starten. Also dachte ich, das lehre mehr nützliches als nur Animationen zu verketten. Ich werde meiner Antwort einige Informationen zur Animationsverkettung hinzufügen. – jfriend00

Verwandte Themen