Come fare in modo che jQuery attenda fino al termine di un effetto?


107

Sono sicuro di averlo letto l'altro giorno ma non riesco a trovarlo da nessuna parte.
Ho un fadeOut()evento dopo il quale rimuovo l'elemento, ma jQuery sta rimuovendo l'elemento prima che abbia la possibilità di finire in dissolvenza.
Come faccio a fare in modo che jQuery attenda che l'elemento sia sbiadito, quindi lo rimuova?

Risposte:


167

È possibile specificare una funzione di callback:

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

Documentazione qui .


Bingo. Pensavo fosse così, ma quello che dovevo fare era inserire la mia intera funzione lì non solo la parte di rimozione. PS Se qualcuno è interessato, il libro in cui l'ho letto e che ora ho ritrovato è Learning JQuery - Better Interaction and Design. Grazie ancora
uriDium

Se qualcuno ha un vecchio jQuery, allora questo bug di "richiamata con animazione" era brutto: bugs.jquery.com/ticket/5684
JustAMartin

178

Con la versione 1.6 di jQuery puoi utilizzare il .promise()metodo.

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

4
Questo è ridondante per la maggior parte delle animazioni jQuery poiché ci sono argomenti di callback sulla maggior parte dei metodi, ma usando promise()o when()e done()puoi sfruttare alcuni comportamenti molto interessanti da metodi di terze parti, o anche i tuoi. +1 per il significato .promise()!
stuartc

4
Non l'ho mai sentito prima, mi sono appena salvato il sedere.
prismspecs

1
nel mio caso, stavo cercando di accedere all'animazione corrente di un elemento che stava accadendo da qualche altra parte nel mio codice, e quindi non avevo accesso alla sua richiamata. +1
Kristian

11
L'uso di promise () consente anche di impostare una singola richiamata per quando tutto è finito. Se chiami fadeOut () su un set di 10 cose, ci sarà un callback per ogni cosa con 'this' impostato allo scope appropriato. Se vuoi sparare solo una volta, questa funzione è davvero utile. Inoltre: se si anima su un selettore che risulta corrispondere a zero elementi, il normale callback non verrà mai attivato. Promise () sparerà alla fine, qualunque cosa accada.
zslayton

6
Puoi anche concatenarlo in questo modo:$(selector).fadeOut('slow').promise().done(function(){...});
Syclone

9

Puoi anche $.when()aspettare fino al promisetermine:

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

Nel caso in cui tu stia facendo una richiesta che potrebbe anche fallire, puoi anche fare un ulteriore passo avanti:

$.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
Questa parte di questa risposta utilizzando $.when()non funziona perché myEvent()non restituisce una promessa e si $.when()aspetta che tu le passi una o più promesse affinché faccia il suo lavoro.
jfriend00

6

se è qualcosa che desideri cambiare, dissolvendone uno e dissolvendone un altro nello stesso punto, puoi posizionare un attributo {position: absolute} sui div, in modo che entrambe le animazioni vengano riprodotte l'una sull'altra e non hai attendere la fine di un'animazione prima di avviare la successiva.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.