animateвызывает свой обратный вызов один раз для каждого элемента в наборе, который вы вызываете animate:
При поставке, то start, step, progress, complete, done, fail, и alwaysобратные вызовы называются на основе каждого элемента ...
Поскольку вы анимируете два элемента ( htmlэлемент и bodyэлемент), вы получаете два обратных вызова. (Для тех, кто задается вопросом, почему OP анимирует два элемента, это потому, что анимация работает bodyв некоторых браузерах, но htmlв других браузерах.)
Чтобы получить один обратный вызов после завершения анимации, animateдокументы указывают на использование promiseметода для получения обещания для очереди анимации, а затем использование thenдля постановки обратного вызова в очередь:
$("html, body").animate(/*...*/)
.promise().then(function() {
// Animation complete
});
(Примечание: Кевин Б. указал на это в своем ответе, когда вопрос был впервые задан. Я не сделал этого до четырех лет спустя, когда заметил, что он отсутствует, добавил его и ... затем увидел ответ Кевина. Пожалуйста, дайте его ответ люблю это заслуживает. Я подумал, так как это принятый ответ, я должен оставить его.)
Вот пример, показывающий как обратные вызовы отдельных элементов, так и общий обратный вызов завершения:
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. Пора снова включить мой мозг. Спасибо