2012-02-27 14 views
5

nie mogę użyć wywołania zwrotne, bo mam scenariusz tak (pseudo-kod):Synchroniczne animacje w jQuery, bez użycia połączeń zwrotnych?

$('.box').on('click', function() { 
    $('.expanded-box').animate({ 
     // shrink it 
    }); 

    $(this).animate({ 
     // grow it 
     $(this).addClass('expanded-box'); 
    }); 
}); 

nie mogę umieścić animację ekspansji w zwrotnego dla animacji expanded-box wzrostu, ponieważ nie zawsze może się zdarzyć . Ale potrzebuję drugiej animacji, aby poczekać, aż skończy się poprzednia. Jak mogę to zrobić?

+0

Co masz na myśli mówiąc „to nie zawsze może się zdarzyć.”? Czy masz na myśli, że '.expanded-box' może nie istnieć? –

Odpowiedz

7

Od jQuery 1.6, można użyć promise() do uzyskania Promise object że zostanie rozwiązany, gdy wszystkie animacje na danym elemencie zostały zakończone. Ponadto dokumentacja mówi:

Użycie .promise() na kolekcji bez aktywnej animacji zwraca rozstrzygniętą obietnicę .

Dlatego to dobrze nadaje się do przypadku użycia, można napisać:

$('.box').on('click', function() { 
    var $this = $(this); 
    $('.expanded-box').animate({ 
     // shrink it 
    }).promise().done(function() { 
     $this.animate({ 
      // grow it 
     }).addClass('expanded-box'); 
    }); 
}); 
+0

Super, nawet nie wiedział o "obietnicy()" - dzięki! Działa również na wiele różnych metod. – CaptSaltyJack

+0

Czym to się różni od umieszczania drugiej części w pełnym oddzwanianiu pierwszej animacji? – nnnnnn

+1

@nnnnnn, jeśli '$ (". Expand-box ")' nie pasuje do niczego, callback 'complete' nie zostanie wywołany, ponieważ jest wywoływany raz dla każdego dopasowanego elementu. Z drugiej strony, 'obietnica()' zwraca rozstrzygnięty obiekt "obietnica", jeśli został wywołany na pustym obiekcie jQuery, dlatego upewniając się, że funkcja przekazywana do 'done()' jest wywoływana we wszystkich przypadkach (tj. Nawet przy pierwszym kliknięciu, gdy nie ma jeszcze rozwiniętego pola). –

1

Można zaimplementować kod drugiej animacji w funkcji, a następnie wywołać tę funkcję z wywołania zwrotnego pierwszej animacji, wywołując ją, jeśli pierwsza animacja się nie stanie. Zakładając, że ten pomysł jest do kurczyć jakąś inną kontrolę, która miała klasę „rozszerzony-Box” z poprzedniej kliknij:

$('.box').on('click', function() { 
    var $this = $(this), 
     $exp = $(".expanded-box"); 

    function grow() { 
     $this.animate({ 
      width: "200px", height: "100px" 
     }).addClass('expanded-box'); 
    } 

    if ($exp.length > 0) { 
     $exp.animate({ 
      width: "100px", height: "50px" 
     }, grow).removeClass("expanded-box"); 
    } else { 
     grow(); 
    }   
});​ 

Demo: http://jsfiddle.net/PXddm/

+0

Cool. Myślałem o tym, ale liczyłem na bardziej eleganckie rozwiązanie. Myślałem, że w jQuery była jakaś kolejka animacji. – CaptSaltyJack

+0

Istnieje z pewnością funkcja kolejki animnacji. Stosował tylko jeden element, ale "Od jQuery 1.7 opcja kolejki może również akceptować ciąg znaków, w którym to przypadku animacja jest dodawana do kolejki reprezentowanej przez ten ciąg." - ale nigdy nie korzystałem z tej funkcji, więc nie jestem pewien, jak to działa. – nnnnnn

Powiązane problemy