.animate() 的回调被调用两次 jquery

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8790752/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 11:02:18  来源:igfitidea点击:

Callback of .animate() gets called twice jquery

jquerycallback

提问by Anonymous

Since I added some scrollTop-animation, some parts of my callback get called twice:

由于我添加了一些scrollTop-animation,我的回调的某些部分会被调用两次:

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

It only seems to repeat the .show(), at least I don't have the impression that the load()or the .fadeIn()get called a second time too. The .show()gets repeated as soon as it has finished for the first time. Setting the scrollTop animation-speed to 0didn't help by the way!

它似乎只是重复了.show(),至少我没有第二次调用load()或 的印象.fadeIn()。在.show()得到尽快,因为它已经完成了第一次重复。0顺便说一下,将 scrollTop 动画速度设置为没有帮助!

I assume it has something to do with the animation-queue, but I can't figure out how to find a workaround and especially whythis is happening.

我认为它与动画队列有关,但我不知道如何找到解决方法,尤其是为什么会发生这种情况。

回答by Kevin B

To get a single callback for the completion of multiple element animations, use deferred objects.

要获得完成多个元素动画的单个回调,请使用延迟对象。

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

See the jQuery API for detailed description of the Promiseand Deferred Objects.

有关PromiseDeferred Objects 的详细说明,请参阅 jQuery API 。

回答by T.J. Crowder

animatecalls its callback once for each elementin the set you call animateon:

animate为您调用的集合中的每个元素调用一次回调animate

If supplied, the start, step, progress, complete, done, fail, and alwayscallbacks are called on a per-element basis...

如果提供的startstepprogresscompletedonefail,和always回调称为对每个元素的基础上...

Since you're animating two elements (the htmlelement, and the bodyelement), you're getting two callbacks. (For anyone wonderingwhy the OP is animating two elements, it's because the animation works on bodyon some browsers but on htmlon other browsers.)

由于您正在为两个元素(html元素和body元素)设置动画,因此您将获得两个回调。(对于任何想知道为什么OP 对两个元素进行动画处理的人,这是因为动画body在某些浏览器上有效html,但在其他浏览器上有效。)

To get a singlecallback when the animation is complete, the animatedocs point you at using the promisemethod to get a promise for the animation queue, then using thento queue the callback:

要在动画完成时获得单个回调,animate文档指出您使用该promise方法获取动画队列的承诺,然后使用then将回调排队:

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

(Note: Kevin B pointed this out in his answerwhen the question was first asked. I didn't until four years later when I noticed it was missing, added it, and...then saw Kevin's answer. Please give his answer the love it deserves. I figured as this is the accepted answer, I should leave it in.)

(注意:Kevin B第一次问这个问题时在他的回答中指出了这一点。直到四年后我才注意到它不见了,添加了它,然后……然后看到了 Kevin 的回答。请给出他的回答爱它应得的。我想这是公认的答案,我应该把它留在里面。)

Here's an example showing both the individual element callbacks, and the overall completion callback:

这是一个显示单个元素回调和整体完成回调的示例:

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>