且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-11-03 22:29:46

animate 调用其回调一次 在 p>如果提供,开始步骤进度完成完成失败 $ c> always 每个元素调用回调


由于您要对两个元素( html 元素和 body 元素)进行动画处理,因此获得两个回调。 (对于任何人想知道为什么OP是动画的两个元素,这是因为动画在 body 在一些浏览器,但在 html )。



完成后, animate docs指向您使用 承诺 方法获取动画队列的承诺,然后使用然后将回调排队:

  $(html,body)animate(/*...*/)
.promise
//动画完成
});

(注意:Kevin B指出了这一点在问题第一次询问时,我没有,直到四年后,当我注意到它缺失,添加它,然后看到凯文的回答



这里是一个例子,显示两个个别元素回调和整个完成回调:



  jQuery(function($){$(#one,#two)。 animate({marginLeft:30em},function(){//每个元素显示调用(Done animating+ this.id);})promise (Done with animation);});函数显示(msg){$(< p>)。html(msg).appendTo(document.body); }});  

 < div id =one >我是一个< / div>< div id =two>我是两个< / div>< script src =https://ajax.googleapis.com/ajax/libs/jquery/ 1.11.1 / jquery.min.js>< / script>  


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

$('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 0 didn't help by the way!

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

animate calls its callback once for each element in the set you call animate on:

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

Since you're animating two elements (the html element, and the body element), you're getting two callbacks. (For anyone wondering why the OP is animating two elements, it's because the animation works on body on some browsers but on html on other browsers.)

To get a single callback when the animation is complete, the animate docs point you at using the promise method to get a promise for the animation queue, then using then to queue the callback:

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

(Note: Kevin B pointed this out in his answer when 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.)

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>