.Animate () 'nin geri araması iki kez jquery çağrılıyor


104

Biraz scrollTop-animasyon eklediğim için geri aramamın bazı kısımları iki kez aranıyor:

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

Sadece tekrarlamak gibi görünüyor .show()en azından ben izlenimi yok, load()ya .fadeIn()da ikinci kez denilen olsun. .show()En kısa sürede ilk kez tamamlanır tamamlanmaz tekrarlanan alır. ScrollTop animasyon hızını ayarlama bu 0arada yardımcı olmadı!

Bunun animasyon kuyruğu ile bir ilgisi olduğunu varsayıyorum, ancak nasıl bir geçici çözüm bulacağımı ve özellikle bunun neden olduğunu çözemiyorum.

Yanıtlar:


163

animateÇağırdığınız kümedeki her öğe için geri çağrısını bir kez çağırır animate:

Tedarik edilirse, start, step, progress, complete, done, fail, ve alwaysgeri çağrıları, bir çağırılır başına elemanı bazında ...

İki öğeyi ( htmlöğe ve bodyöğe) canlandırdığınız için , iki geri çağrı alıyorsunuz. ( OP'nin neden iki öğeyi canlandırdığını merak edenler için, bunun nedeni animasyonun bodybazı tarayıcılarda, ancak htmldiğer tarayıcılarda çalışmasıdır.)

Animasyon tamamlandığında tek bir geri arama almak için , animatedokümanlar sizi promiseanimasyon kuyruğu için bir söz alma yöntemi kullanmaya ve ardından thengeri aramayı sıraya koymak için kullanmaya yönlendirir:

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

(Not: Kevin B , soru ilk sorulduğunda cevabında buna işaret etti . Dört yıl sonra eksik olduğunu fark edip ekledim ve ... sonra Kevin'in cevabını görünceye kadar bunu yapmadım. Lütfen cevabını verin Bunu hak ettiğini seviyorum. Kabul edilen yanıtın bu olduğunu düşündüm, içinde bırakmalıyım.)

Hem tek tek öğe geri aramalarını hem de genel tamamlama geri aramalarını gösteren bir örnek:

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>


2
Evet sebep buydu ve aslında neden yazdığımı hatırlayamıyorum html, body. Beynimi yeniden açma zamanı. Teşekkürler
Anonim

21
Muhtemelen sadece html'yi canlandırmanın Webkit'te çalışmayacağı ve Opera'da sadece gövde çalışmayacağı için. Her ikisini de kullanmak, her zaman çalışmasını sağlar, ancak Firefox'ta geri aramayı iki kez tetikler. (Tarayıcıları yanlış almış olabilirim ...)
Jon Gjengset

2
htmlIE için gereklidir ve geri arama, diğer tarayıcıların çoğu için iki kez tetiklenir. Aynı soruna bir çözüm bulmaya çalışıyorum.
Simon Robb

9
Bunu bir bayrak oluşturarak hallettim: var ranOne = false; $('body,html').animate({ scrollTop: scrollTo }, scrollTime, 'swing', function () { if (ranOne) { ...action... ranOne = false; } else { ranOne = true; } }); Keskin bir his veriyor ama "body, html" kullanmak ilk etapta biraz hilekar, bu yüzden. (ech satır sonları olmadığı için üzgünüm, sanırım yorumlar onları göstermiyor)
13:14

1
Inanılmaz! Kaydırma animasyonumun $ ("html, body") ile düzgün çalışmasını sağlamak için saatler harcadım, böylece iki kez ateşlenmesin ve bu cevap beni kurtardı! Teşekkürler!
Vasily Hall

172

Birden çok öğe animasyonunun tamamlanması için tek bir geri arama almak için ertelenmiş nesneleri kullanın.

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

Promise ve Ertelenen Nesnelerin ayrıntılı açıklaması için jQuery API'sine bakın .


Bu, animasyonu bitirdiğimizde ne yapmak istediğimizle ilgili sorun çözüldü, ancak bunun için iki kez arama ve +1 alma sorunu var, ancak animasyon işleminin iki kez çağrılıp çağrılmadığını bilmiyorum ?!
QMaster

1
Canlandırma işlemi iki kez çağrılmaz, geri çağırma seçilen her öğe için bir kez çağrılır. Bu nedenle, 8 liste öğesi seçer ve bunları sola doğru hareketlendirirseniz, geri arama 8 kez yürütülecektir. Çözümüm, 8'in tamamı bittiğinde size tek bir geri arama sağlıyor.
Kevin B

@KevinB, iyi bir çözüm ve kendi geri arama sorunlarımın da çözülmesine yardımcı oldu. Teşekkürler.
lislis

Bunun ilgi çekici bir cevap olduğunu düşündüm, ancak maalesef istenmeyen sonuçları var. Söz, jQuery kümesinin öğeleri geçerli animasyonu bitirene kadar (bu harika olurdu) sadece geri arama yürütmesini geciktirmez. Yalnızca setin tüm bekleyen animasyonları tamamlandıktan sonra çözülür . Bu nedenle, birinci animasyon çalışıyorken ikinci bir animasyon ayarlanırsa, ilk animasyon için amaçlanan geri arama, ikinci animasyon bitene kadar çalışmaz. Bu çöp kutusuna bakın .
hashchange

1
Bu doğru, seçilen öğeler için mevcut tüm animasyonların tamamlanmasını bekler . Sadece bu zincirde başlayanları bekleyecek kadar akıllı değil (ne de olmamalı)
Kevin B
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.