Jak sprawić, by jQuery czekało, aż efekt zostanie zakończony?


107

Jestem pewien, że czytałem o tym kiedyś, ale nie mogę go nigdzie znaleźć.
Mam fadeOut()zdarzenie, po którym usuwam element, ale jQuery usuwa element, zanim będzie miał szansę zakończyć zanikanie.
Jak sprawić, by jQuery czekało, aż element wyblaknie, a następnie go usunie?

Odpowiedzi:


167

Możesz określić funkcję zwrotną:

$(selector).fadeOut('slow', function() {
    // will be called when the element finishes fading out
    // if selector matches multiple elements it will be called once for each
});

Dokumentacja tutaj .


Bingo. Myślałem, że tak, ale to, co musiałem zrobić, to umieścić całą moją funkcję, a nie tylko część do usunięcia. PS Jeśli ktoś jest zainteresowany książką, w której ją przeczytałem, a teraz znowu znalazłem, jest Learning JQuery - Better Interaction and Design.
Jeszcze

Jeśli ktoś ma stare jQuery, to ten błąd „animacja zakończona oddzwonieniem” był paskudny: bugs.jquery.com/ticket/5684
JustAMartin

178

W wersji jQuery 1.6 możesz skorzystać z .promise()metody.

$(selector).fadeOut('slow');
$(selector).promise().done(function(){
    // will be called when all the animations on the queue finish
});

4
Jest to zbędne dla większości animacji jQuery, ponieważ istnieją argumenty wywołania zwrotnego na większości metod, ale przy użyciu promise()lub when()i done()można wykorzystać niektóre bardzo fajne zachowanie od 3 metod partyjnych, a nawet własne. +1 za intencje .promise()!
stuartc,

4
Nie słyszałem tego wcześniej, po prostu uratowałem mój tyłek.
prismspecs

1
w moim przypadku próbowałem uzyskać dostęp do bieżącej animacji elementu, który dzieje się w innym miejscu w moim kodzie, przez co nie miałem dostępu do jego wywołania zwrotnego. +1
Kristian

11
Użycie promise () pozwala również na skonfigurowanie pojedynczego wywołania zwrotnego, gdy wszystko jest zrobione. Jeśli wywołasz fadeOut () na zestawie 10 rzeczy, nastąpi jedno wywołanie zwrotne dla każdej rzeczy z wartością „this” ustawioną na odpowiedni zakres. Jeśli chcesz odpalić tylko raz, ta funkcja jest naprawdę pomocna. Ponadto: jeśli animujesz na selektorze, który okazuje się pasować do zero elementów, normalne wywołanie zwrotne nigdy nie zostanie uruchomione. Promise () uruchomi się na końcu bez względu na wszystko.
zslayton

6
Możesz również połączyć to w następujący sposób:$(selector).fadeOut('slow').promise().done(function(){...});
Syclone

9

Możesz równie dobrze $.when()poczekać, aż promiseskończysz:

var myEvent = function() {
    $( selector ).fadeOut( 'fast' );
};
$.when( myEvent() ).done( function() {
    console.log( 'Task finished.' );
} );

Jeśli wykonujesz żądanie, które równie dobrze może się nie powieść, możesz nawet pójść o krok dalej:

$.when( myEvent() )
    .done( function( d ) {
        console.log( d, 'Task done.' );
    } )
    .fail( function( err ) {
        console.log( err, 'Task failed.' );
    } )
    // Runs always
    .then( function( data, textStatus, jqXHR ) {
        console.log( jqXHR.status, textStatus, 'Status 200/"OK"?' );
    } );

2
Ta część odpowiedzi $.when()nie działa, ponieważ myEvent()nie zwraca obietnicy i $.when()oczekuje, że przekażesz jej jedną lub więcej obietnic, aby wykonała swoją pracę.
jfriend00

6

jeśli jest to coś, co chcesz zmienić, wyciszając jedną i wygaszając drugą w tym samym miejscu, możesz umieścić atrybut {position: Absolut} na elementach div, aby obie animacje były odtwarzane jedna na drugiej i nie masz poczekać na zakończenie jednej animacji przed uruchomieniem następnej.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.