2016-01-31 9 views
8

Animiere die Div, nachdem die vorherige Div-Animation mit deferred object abgeschlossen wurde. Diese einfache Methode funktioniert mit den beiden Funktionen f1 und f2, aber wenn ich f3 einführe, schlägt es fehl.Eine Div-Animation nach der anderen mit einem verzögerten Objekt

Gibt es eine bessere Möglichkeit, dies mit dem verzögerten Objekt zu erreichen?

JSFiddle: https://jsfiddle.net/j0bgzjvd/

var deferred = $.Deferred(); 
 

 
function animationAgent(element, prevElement) { 
 
    $(prevElement).promise().done(function() { 
 
    return $(element).css("display", "block").animate({width:360},2000, "linear") 
 
    }); 
 
} 
 

 
function f1() { 
 
    animationAgent("#div1"); 
 
} 
 

 
function f2() { 
 
    animationAgent("#div2", "#div1"); 
 
} 
 

 
function f3() { 
 
    animationAgent("#div3", "#div2"); 
 
} 
 

 
deferred.resolve(); 
 
deferred.done([ f1, f2, f3 ]);
div { 
 
    width: 200px; 
 
    height: 200px; 
 
    background-color: red; 
 
    margin-bottom: 10px; 
 
    display: none; 
 
}
<script src="https://code.jquery.com/jquery-1.10.2.js"></script> 
 

 
<div id="div1"></div> 
 
<div id="div2"></div> 
 
<div id="div3"></div>

+0

Können Sie einen Ausschnitt oder ist mit diesem Problem hinzu? Irgendwelche Fehler in der 'Konsole'? –

+0

Bitte beachten Sie die JSFiddle in der Post aktualisiert. In der Konsole sind keine Fehler vorhanden. Ich möchte, dass die Divs nacheinander in Harmonie animieren, aber wie Sie sehen können, führt Funktion 3 zu einer Störung in der Animationsfolge. Durch das Herausnehmen von f3 können f1 und f2 nacheinander animiert werden - @MoshFeu – jcoulston2

+0

Prüfen Sie, ob die folgende Antwort hilfreich ist. @ jcoulston2 –

Antwort

1

Sie finden es einfacher:

  • animationAgent() in eine einfache, Versprechen-Rückkehr Arbeiter Funktion machen, dass sie nur über das Element kennt beseelt und nichts über die Reihenfolge, in der es verwendet werden soll (dh prevElement auslassen),
  • veranlassen für Funktionen f1(), f2() und f3(), um das Versprechen zurückzugeben, das von animationAgent() zurückgegeben wird.

Dann haben Sie die Grundlage für den Aufbau einer zuverlässigen Animationssequenz.

function animationAgent(element) { 
    return $(element).css("display", "block").animate({width:360}, 2000, "linear").promise(); 
} 
function f1() { 
    return animationAgent("#div1"); 
} 
function f2() { 
    return animationAgent("#div2"); 
} 
function f3() { 
    return animationAgent("#div3"); 
} 

f1().then(f2).then(f3); 

DEMO

Alternativ konstruieren, um die Kette .then mechanistisch aus einem Array von Funktionsreferenzen:

function animationAgent(element) { 
    return $(element).css("display", "block").animate({width:360}, 2000, "linear").promise(); 
} 
function f1() { 
    return animationAgent("#div1"); 
} 
function f2() { 
    return animationAgent("#div2"); 
} 
function f3() { 
    return animationAgent("#div3"); 
} 

[f1, f2, f3].reduce(function(promise, fn) { 
    return promise.then(function() { 
     return fn(); 
    }); 
}, $.when()); 

DEMO

oder, wie die drei Animationen identisch, y ou kann den Bedarf für einzelne Funktionen vermeiden, indem die .then Kette aus einer Vielzahl von Element-Selektoren Konstruktion und animationAgent() Aufruf direkt:

function animationAgent(element) { 
    return $(element).css("display", "block").animate({width:360}, 2000, "linear").promise(); 
} 

['#div1', '#div2', '#div3'].reduce(function(promise, selector) { 
    return promise.then(function() { 
     return animationAgent(selector); 
    }); 
}, $.when()); 

DEMO

0

jemals daran gedacht, Rückrufe in der Animation-Funktion?

Hier ist ein Beispiel mit fadeOut: https://jsfiddle.net/0r7e2wco/

fadeOutInTurn([ 
    $("#div1"), 
    $("#div2"), 
    $("#div3"), 
    $("#div4"), 
]); 

//Fades out elements one after another 
function fadeOutInTurn(elements) { 
    var x = 0; 
    function animate() { 
     $(elements[x]).fadeOut(3000, function() { 
      if(x < elements.length - 1) { 
       x++; 
       animate(); 
      } 
     }); 
    } 
    animate(); 
} 
+1

Ich denke, dass er es mit 'verzögerten Objekt 'will .. –

+0

" Gibt es einen besseren Weg, ich kann das erreichen? " Ich nahm an, er wollte bessere Wege kennen, um Elemente nacheinander zu animieren. – seahorsepip

+0

Wenn er ein Objekt benutzen möchte, das er benutzt, sollte er notify() und progress() anstelle von resolve() und done() verwenden, damit ein Objekt unbegrenzt oft benutzt werden kann ^^ Aber ich verstehe es nicht Warum würde jemand ein bestimmtes Muster verwenden, um einige Elemente zu animieren ... – seahorsepip

0

nicht sicher, aber ich denke, das ist das, was Sie wollen.

Arbeitsbeispiel fiddle

Ich glaube, Sie deferred.done() hoffen, wird f1, f2, f3 einer nach dem anderen ausführen gut es tut das. Es wartet jedoch nicht darauf, dass die in diesen Funktionen aufgerufenen Animationen beendet werden, bevor die nächste Funktion aufgerufen wird.

versuchen Sie, die Funktionsaufrufe auf der Konsole mit console.log() protokollieren und Sie werden wissen.

hier ist die aktualisierte JavaScript-Code -

var deferred = $.Deferred(); 
var lock = 1; 

function animationAgent(element, id, prevElement) { 
    var interval; 
    var flag = 0; 
    if (id != lock) { 
    interval = setInterval(function() { 
     if (id == lock) { 
     clearInterval(interval); 
     animationAgent(element, id, prevElement); 
     } 
    }, 1000); 
    }else{ 
    $(prevElement).promise().done(function() { 
     lock++; 
     return $(element).css("display", "block").animate({ 
     width: 360 
     }, 2000, "linear"); 
    }); 
    } 
} 

function f1() { 
    return animationAgent("#div1", 1); 
} 

function f2() { 
    return animationAgent("#div2", 2, "#div1"); 
} 

function f3() { 
    return animationAgent("#div3", 3, "#div2"); 
} 

deferred.resolve(); 
deferred.done([f1, f2, f3]);