2011-02-09 20 views
10

Ho più animazioni su un singolo oggetto e ho bisogno di interrompere un'animazione specifica piuttosto che tutte. Non sembra che il metodo .stop() possa farlo.Arresto di animazioni jQuery specifiche

Ad esempio, durante l'animazione simultanea dell'opacità e della larghezza, potrebbe essere necessario annullare l'animazione di opacità mentre si sta ancora completando l'animazione della larghezza. Sembrerebbe che questo non sia possibile, ma spero che qualcuno conosca un trucco o una chiamata API che mi manca.

Nota: Non sto parlando di animazioni in coda, sto cercando di animare più attributi allo stesso tempo, con la possibilità di fermare alcuni di quelli attribuiscono animazioni dopo che hanno già iniziato

+0

avrei pensato che ci sarebbe un modo utilizzando le code di nome personalizzato, ma non sembrare come il '.Stop()' metodo può avere come bersaglio una coda specifica (per quanto posso dillo comunque). – user113716

+0

Per ora ho richiesto di aggiungere questa funzione http://bugs.jquery.com/ticket/8227 – slifty

+0

Quali sono i criteri per l'interruzione di un'animazione? Si basa su un'azione dell'utente? – Jeff

risposta

8

Odio essere un ragazzo che risponde alla sua stessa domanda (grazie mille per le risposte dettagliate e mettendo il potere del cervello in esso!) Ma ho trovato una risposta diretta. Apparentemente esiste un parametro per il metodo .animate() chiamato "queue" che è impostato su true ma è possibile impostarlo su false per far sì che l'animazione abbia luogo immediatamente.

Ciò significa che impostando la coda su falso è possibile eseguire più animazioni utilizzando chiamate separate senza dover attendere il completamento della precedente. Meglio ancora, se provi a eseguire un'animazione per una proprietà che è già animata, la seconda sovrascriverà la prima. Questo significa che puoi fermare l'animazione di una proprietà semplicemente "animandola" sul suo valore corrente con una durata di 0, usando la coda "false".

Un esempio:

$myElement = $("#animateElement"); 
$myElement.animate({width: 500}, {duration: 5000}); 
$myElement.animate({height: 500}, {duration: 5000, queue: false}); 
// ... Wait 2 seconds ... 
$myElement.animate({width: $myElement.width()}, {duration: 0, queue: false}); 

Another option è stata suggerita da un collaboratore jQuery graziosa che ha risposto alla mia richiesta di miglioramento. Questo sfrutta la possibilità di utilizzare una funzione di passo su un'animazione (le funzioni di passo vengono chiamate in ogni punto dell'animazione e puoi manipolare i parametri di animazione in base a qualsiasi criterio tu desideri). Sebbene anche questo avrebbe potuto risolvere il problema, ho ritenuto che fosse molto più sporco dell'opzione "coda: falso".

3

Dopo aver pensato su questo un po 'più difficile su questo, ho capito che quello che stai cercando di fare non è fattibile facilmente a causa del modo in cui le animazioni sono gestite in jQuery.

Poiché le animazioni sono gestite da una coda, non è possibile eseguire le animazioni simultanee sullo stesso elemento senza che siano nella stessa funzione.

Vale a dire,

$(element).animate(aThing, aTime); 
      .animate(anotherThing, anotherTime); 

non ha intenzione di correre in parallelo. athing finirà in aTime, seguito da anotherThing della durata di anotherTime.

Così, si può realizzare solo modifiche multiple facendoli nella stessa funzione:

$(element).animate({aThing: aValue, anotherThing: anotherValue}, aTime); 

ecco una rapida spiegazione dell'anatomia di come funzioni di animazione sono gestite all'interno di jQuery.

un oggetto Timer viene assegnato l'elemento per la durata dell'animazione:

function t(gotoEnd) { 
    return self.step(gotoEnd); 
} 

t.elem = this.elem; 
jQuery.timers.push(t); 

Quando si chiama la funzione di arresto, rimuove il timer da timer:

// go in reverse order so anything added to the queue during the loop is ignored 
for (var i = timers.length - 1; i >= 0; i--) { 
    if (timers[i].elem === this) { 
     if (gotoEnd) { 
      // force the next step to be the last 
      timers[i](true); 
     } 

     timers.splice(i, 1); 
    } 
} 

Quindi, ci non è un modo per rimuovere una proprietà specifica di una funzione di animazione poiché il timer stesso viene ucciso.


L'unico modo ho potuto pensare di compiere sarebbe quello di tenere traccia del tempo di inizio e la durata, ri-accodamento l'animazione e l'arresto quello attuale.

var start = $.now(); 
var duration = 5000; 

$(element).animate({opacity: '0.5', width: '500px'}, duration); 

...

var remaining = duration - ($.now() - start); 
$(element).animate({opacity: '0.5', remaining) 
      .stop(); 
+0

Mille grazie per la risposta! Potrei non capire appieno, ma sembra che questo codice causerà un'animazione della larghezza di 5 secondi, a quel punto inizierà l'animazione dell'opacità. Devo essere in grado di eseguire contemporaneamente le animazioni di larghezza e opacità (vale a dire, sia la larghezza che l'opacità cambiano), con la possibilità di arrestare l'una o l'altra prima del completamento senza fermarle entrambe. – slifty

+0

Va bene, ho rivisto la mia risposta ora che ho effettivamente una migliore comprensione della tua domanda:). –

+0

Ciao Ian - Volevo solo ringraziarvi tanto per una risposta così dettagliata. Sono stato in grado di trovare una soluzione diretta che non richiede alcun tipo di tracciamento, quindi sfortunatamente non posso darti il ​​tag della risposta :(. Spero che tu possa usare la soluzione un giorno! – slifty

1

Invece di un'animazione, si può suddividerlo in diverse animazioni più piccoli (cioè animare l'opacità 0-20%, quindi animate 20-40%, quindi 40-60%, ecc.) E invece di .stop() -ing l'animazione, non lo riavvii?

0

Uso il plug-in jQuery per animare una dozzina di presentazioni sulla stessa pagina utilizzando vari tipi di animazione (salviette, riproduzioni, zoom, ecc.). Ho poi avuto il mio piccolo script per sbiadire un po 'le immagini come hai passato il mouse ogni presentazione:

# This code stops all current animations on an element 

$(".box img").hover(
    function(){ 
     $(this).stop().fadeTo("slow",0.7); 
    }, 
    function(){ 
     $(this).stop().fadeTo("fast",1); 
    } 
); 

Il problema è stato la funzione .stop() è stato anche l'arresto il plugin ciclo in esso tracce - i miei salviettine, mescola e zoom si fermava bruscamente a metà della loro animazione lasciando la pagina fratturata e fuori posizione. La soluzione era quella di implementare la coda "false" idea:

# This code suited me better - it leaves the other running animations untouched 

$(".box img").hover(
    function(){ 
     $(this).animate({opacity: 0.7}, {duration: 1000, queue: false}); 
    }, 
    function(){ 
     $(this).animate({opacity: 1}, {duration: 250, queue: false}); 
    } 
); 
1

AGGIORNAMENTO 2013

Come di jQuery 1.7 è possibile utilizzare .animate() con una coda di nome, e utilizzare .stop(queuename) per fermare solo quelle animazioni nella coda.


http://api.jquery.com/stop/

Problemi correlati