2013-01-30 21 views
10

See demo: jsFiddleCome evitare questo strano jQuery .animate() lag?

  • Ho una forma semplice che viene attivato quando si fa clic 'show'/'annullare'
  • Tutto funziona bene, ma se si fa clic su 'annullare' poco dopo la forma è rivelato, c'è un buon ritardo di 2-3 secondi prima che l'animazione inizi anche.
  • Questo non accade se si attende qualche secondo prima di fare clic su "annulla".
  • Il ritardo si verifica in tutti i browser testati (ad esempio, ff, chrome).

1. Che cosa potrebbe causare questo ritardo e come può essere prevenuto?

2. Esiste un modo migliore per codificare questa sequenza di animazioni, che potrebbe impedire eventuali ritardi?

HTML:

<div id="newResFormWrap"> 
    <form id="newResForm" action="" method="post" name="newRes"> 
     <div id="newResFormCont"> 
      <h3>title</h3> 
      <p>form!</p> 
      <div class="button" id="cancelNewRes">Cancel</div> 
     </div> 
    </form> 
</div> 
<div class="button" id="addRes">show</div> 

jQuery:

$("#newResForm").css({opacity: 0}); 

$("#addRes").click(function() { 
    toggleNewRes() 
}); 
$("#cancelNewRes").click(function() { 
    toggleNewRes() 
}); 

//toggleNewRes 
function toggleNewRes() { 
    if ($("#newResFormWrap").css('display') == "none") {//if hidden 
     $("#addRes").animate({ opacity: 0 }, 'fast', function() { 
      $("#newResFormWrap").toggle('fast', function(){ 
       $("#newResForm").animate({ opacity: 100 },2000); 
      }); 
     }); 
    } else { //if visible 
     $("#newResForm").animate({ opacity: 0 }, 100,function() { 
      $("#newResFormWrap").toggle('fast', function(){ 
       $("#addRes").animate({ opacity: 100 }); 
      }); 
     }); 
    } 
} 

risposta

20

Assicurarsi di cancellare la coda WHE n iniziare una nuova animazione con stop():

$("#newResForm").stop().animate({ opacity: 0 }, 100,function() { 
     $("#newResFormWrap").toggle('fast', function(){ 
      $("#addRes").animate({ opacity: 100 }); 
       // ... 

che cosa sta causando il ritardo è il fatto che il vostro tempo di 2 secondi l'animazione $("#newResForm").animate({ opacity: 100 },2000) non è ancora finito. JQuery mette le animazioni di default in una coda, aspettando che una finisca prima che inizi il prossimo. Si cancella la coda con stop(), che è particolarmente utile se si dispone di due animazioni contraddittorie (come un'animazione aperta e chiusa o un'animazione mouseover/mouseout). In effetti potresti trovare una buona pratica per iniziare tutte le tue catene di animazioni con stop() a meno che tu non sappia che vuoi farle fare la coda con le animazioni precedenti che potrebbero essersi verificate altrove.

Entrando in argomenti più avanzati, è anche possibile denominare code diverse, in modo che ad esempio le animazioni al passaggio del mouse e le animazioni di espansione/compressione siano trattati separatamente ai fini di stop(). Vedere l'opzione queue (quando viene fornita una stringa) a http://api.jquery.com/animate/ per ulteriori dettagli.

+0

bella spiegazione – Roy

+0

Risposta perfetta. –

1

Aggiungere .stop() prima chiama il tuo animato:

function toggleNewRes() { 
    if ($("#newResFormWrap").css('display') == "none") {//if hidden 
     $("#addRes").stop().animate({ opacity: 0 }, 'fast', function() { 
      /... 
     }); 
    } else { //if visible 
     $("#newResForm").stop().animate({ opacity: 0 }, 100,function() { 
      /... 
     }); 
    } 
} 
+0

prima di tutto, questo funziona (accetterà in 10 minuti), ma, perché è anche necessario? Posso vedere chiaramente che l'animazione è finita – Roy

+0

@Roy è stato coinvolto in un mini-incontro;) –

+0

nessun problema grazie per la tua risposta – Roy

1

tenta di utilizzare stop():

Here is jsfiddle.

if ($("#newResFormWrap").is(':visible')) {//this way is eaiser to check 
    $("#addRes").stop(true,false).animate({ opacity: 0 }, 'fast', function() { 
     $("#newResFormWrap").toggle('fast', function(){ 
      $("#newResForm").animate({ opacity: 100 },2000); 
     }); 
    }); 
} 
1

paio di cose. Prima controlla questo JSFiddle per vederlo in azione.

Il problema è che la dissolvenza in animazione dura 2 secondi. Quindi, quando lo chiudi entro 2 secondi, avverti un ritardo.

Ho ricalibrato i tempi per garantire che non vi siano ritardi.Vedi se ti piacciono e sentiti libero di cambiarli come preferisci.

if ($("#newResFormWrap").css('display') == "none") {//if hidden 
    $("#addRes").animate({ opacity: 0 }, 'fast', function() { 
     $("#newResFormWrap").toggle(0, function(){ 
      $("#newResForm").animate({ opacity: 100 },400); 
     }); 
    }); 
} else { //if visible 
    console.log('click'); 
    $("#newResForm").animate({ opacity: 0 }, 0, function() { 
     console.log('animated'); 
     $("#newResFormWrap").toggle(0) 
    }); 
    $("#addRes").animate({ opacity: 100 }, 'fast'); 
} 
+0

Immagino che il metodo stop() sopra menzionato sia anche un fattore importante nella soluzione .. Ma grazie per la risposta – Roy