web-dev-qa-db-ja.com

.animate()のコールバックが2回jqueryで呼び出される

scrollTop- animationを追加したため、コールバックの一部が2回呼び出されます。

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

.show()を繰り返すように思えますが、少なくともload()または.fadeIn()が2度目に呼び出されるという印象はありません。 .show()は、初めて終了するとすぐに繰り返されます。 scrollTopアニメーション速度を_0_に設定しても、ちなみに助けにはなりませんでした!

アニメーションキューと関係があると思いますが、回避策を見つける方法がわかりません。特にwhyこれが起こっています。

97
Anonymous

animate は、animateを呼び出すセット内の各要素に対してコールバックを1回呼び出します。

指定した場合、startstepprogresscompletedonefail、およびalwaysコールバックが呼び出されます要素ごとの基礎...

2つの要素(html要素とbody要素)をアニメーション化しているため、2つのコールバックを取得しています。 (疑問に思う人はなぜOPが2つの要素をアニメーション化するのか、それはアニメーションがbodyで動作するためです一部のブラウザーではhtmlで、他のブラウザーでは。)

アニメーションの完了時にsingleコールバックを取得するには、animateドキュメントで promise メソッドを使用してアニメーションキューの約束を取得し、thenを使用してコールバックをキューに入れます。

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

(注:Kevin Bはこれを指摘しました 彼の答えで 質問が最初に尋ねられたとき。それから...ケビンの答えを見ました。彼の答えに値する愛を与えてください。これは受け入れられる答えだと思いましたので、そのままにしておきます。)

個々の要素のコールバックと全体的な完了コールバックの両方を示す例を次に示します。

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>
152
T.J. Crowder

複数の要素アニメーションを完了するための単一のコールバックを取得するには、遅延オブジェクトを使用します。

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

Promise および Deferred Objects の詳細な説明については、jQuery APIを参照してください。

167
Kevin B