Le rappel de .animate () est appelé deux fois jquery

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 et always 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 .