Chamada de .animate () é chamada duas vezes jquery

Desde que adicionei algumas scrollTop scrollTop, algumas partes do meu callback são chamadas duas vezes:

 $('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); }); }); }); 

Parece apenas repetir o .show() , pelo menos eu não tenho a impressão de que o load() ou o .fadeIn() são chamados pela segunda vez também. O .show() é repetido assim que termina pela primeira vez. Definir a velocidade de animação scrollTop para 0 não ajudou pelo caminho!

Eu suponho que tenha algo a ver com a fila de animação, mas não consigo descobrir como encontrar uma solução alternativa e, especialmente, por que isso está acontecendo.

animate chama seu callback uma vez para cada elemento no conjunto que você chama animate on:

Se fornecido, o start , step , progress , complete , done , fail e always retornos de chamada são chamados por elemento

Como você está animando dois elementos (o elemento html e o elemento body ), receberá dois retornos de chamada. (Para qualquer um que esteja se perguntando por que o OP está animando dois elementos, é porque a animação funciona no body de alguns navegadores, mas em html em outros navegadores.)

Para obter um único retorno de chamada quando a animação é concluída, os documentos animate apontam para você usar o método promise para obter uma promise para a fila de animação e, em seguida, usar para enfileirar o retorno de chamada:

 $("html, body").animate(/*...*/) .promise().then(function() { // Animation complete }); 

(Nota: Kevin B apontou isso em sua resposta quando a pergunta foi feita pela primeira vez. Eu não o fiz até quatro anos depois, quando percebi que estava faltando, adicionei e … então vi a resposta de Kevin. Por favor, dê sua resposta amor que merece. Eu percebi como esta é a resposta aceita, eu deveria deixá-lo dentro.)

Veja um exemplo que mostra os retornos de chamada do elemento individual e o retorno de chamada de conclusão geral:

 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

Para obter um único retorno de chamada para a conclusão de várias animações de elementos, use objects adiados.

 $(".myClass").animate({ marginLeft: "30em" }).promise().done(function(){ alert("Done animating"); }); 

Consulte a API do jQuery para obter uma descrição detalhada dos objects Promise e Deferred .