animatellama a su devolución de llamada una vez para cada elemento del conjunto al que llama animate:
Si se suministra, el start, step, progress, complete, done, fail, y alwaysdevoluciones de llamada se denominan en una base por elemento ...
Dado que está animando dos elementos (el htmlelemento y el bodyelemento), obtiene dos devoluciones de llamada. (Para cualquiera que se pregunte por qué el OP está animando dos elementos, es porque la animación funciona bodyen algunos navegadores pero htmlen otros navegadores).
Para obtener una única devolución de llamada cuando la animación esté completa, los animatedocumentos le indican que use el promisemétodo para obtener una promesa para la cola de animación, luego use thenpara poner en cola la devolución de llamada:
$("html, body").animate(/*...*/)
.promise().then(function() {
// Animation complete
});
(Nota: Kevin B señaló esto en su respuesta cuando se hizo la pregunta por primera vez. No lo hice hasta cuatro años después, cuando noté que faltaba, lo agregué y ... luego vi la respuesta de Kevin. Por favor, dé su respuesta el amor se merece. Pensé que como esta es la respuesta aceptada, debería dejarla.)
Aquí hay un ejemplo que muestra tanto las devoluciones de llamada de elementos individuales como la devolución de llamada de finalización general:
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) {
$("<p>").html(msg).appendTo(document.body);
}
});
<div id="one">I'm one</div>
<div id="two">I'm two</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
html, body. Es hora de volver a encender mi cerebro. Gracias