Depuis que j’ai ajouté une animation- scrollTop
, certaines parties de mon callback sont appelées deux fois:
$('html, body').animate({scrollTop: '0px'}, 300,function() { $('#content').load(window.location.href, postdata, function() { $('#step2').addClass('stepactive').hide().fadeIn(700, function() { $('#content').show('slide',800); }); }); });
Il ne semble que répéter le .show()
, au moins je n’ai pas l’impression que le load()
ou le .fadeIn()
sont également appelés une seconde fois. Le .show()
est répété dès qu’il est terminé pour la première fois. Définir la vitesse de l’animation scrollTop sur 0
n’a pas aidé au passage!
Je suppose que cela a quelque chose à voir avec la queue d’animation, mais je ne peux pas trouver comment trouver une solution de contournement et surtout pourquoi cela se produit.
animate
appelle son rappel une fois pour chaque élément de l’ensemble que vous appelez animate
sur:
Si ils sont fournis, les rappels de
start
,step
,progress
,complete
,done
,fail
etalways
sont appelés par élément …
Puisque vous animez deux éléments (l’élément html
et l’élément body
), vous obtenez deux rappels. (Pour ceux qui se demandent pourquoi l’OP anime deux éléments, c’est parce que l’animation fonctionne sur le body
de certains navigateurs, mais sur du html
sur d’autres navigateurs.)
Pour obtenir un seul rappel lorsque l’animation est terminée, les documents d’ animate
vous indiquent comment utiliser la méthode promise
pour obtenir une promesse pour la queue d’animation, puis utiliser then
pour mettre en attente le rappel:
$("html, body").animate(/*...*/) .promise().then(function() { // Animation complete });
(Note: Kevin B l’a souligné dans sa réponse lorsque la question a été posée pour la première fois. Ce n’est que quatre ans plus tard que j’ai remarqué qu’il manquait, l’a ajouté et … a ensuite répondu à Kevin. Je pense que c’est la réponse acceptée, je devrais le laisser.)
Voici un exemple montrant à la fois les rappels d’éléments individuels et le rappel d’achèvement global:
jQuery(function($) { $("#one, #two").animate({ marginLeft: "30em" }, function() { // Called per element display("Done animating " + this.id); }).promise().then(function() { // Called when the animation in total is complete display("Done with animation"); }); function display(msg) { $("").html(msg).appendTo(document.body); } });
I'm one I'm two
Pour obtenir un rappel unique pour l’exécution de plusieurs animations d’élément, utilisez des objects différés.
$(".myClass").animate({ marginLeft: "30em" }).promise().done(function(){ alert("Done animating"); });
Voir l’API jQuery pour une description détaillée des objects Promise et Deferred .