2010-07-16 6 views
0

J'essaie de créer une flèche clignotante. Cependant, lorsque j'exécute ce script dans différents navigateurs, il se comporte mal. IE dit que c'est hors de la mémoire, Chrome est en retard d'une seconde et se comporte bien et dans firefox l'animation est collante.jquery anime running laggy

J'espère que quelqu'un peut trouver un moyen d'animer une flèche clignotante en douceur. Merci

aniPointer($('#arrow')); 

function aniPointer(point) { 
     point.animate({opacity: 1.0}, {duration: 300}) 
      .animate({opacity: 0.2}, {duration: 700}) 
      .animate({opacity: 0.2}, {duration: 300}) 
      .animate({opacity: 1.0}, {duration: 300, complete: aniPointer(point)}) 
    } 

Répondre

4

Vous créez une boucle infinie. Vous l'avez fait intentionnellement, mais il fonctionne beaucoup plus vite que vous ne le pensez. complete prend une référence de fonction. En ajoutant les parens au nom de la fonction de rappel, vous appelez immédiatement aniPointer et transmettez la valeur de retour à complete au lieu de transmettre une référence à aniPointer lui-même pour être déclenché ultérieurement.

Même ainsi, cette séquence est-elle vraiment ce que vous voulez faire?

que vous faites:

go to 1.0 over 300ms 
go to 0.2 over 700ms 
go to 0.2 over 300ms 
go to 1.0 over 300ms 
repeat 

En supposant que vous commencez à 1.0 est en fait:

wait 300ms 
go to 0.2 over 700ms 
wait 300ms 
go to 1.0 over 300ms 
repeat 

Si vous cherchez une impulsion constante que vous pourriez faire quelque chose comme ceci:

function pulse($elem) { 
    return window.setInterval(function() { 
     $elem.animate({opacity: 0.2}, 700) 
      .animate({opacity: 1.0}, 300); 
    }, 1000); 
} 

Ou si vous étiez mise en pause, vous pouvez le faire intentionnellement:

function pulse($elem) { 
    return window.setInterval(function() { 
     $elem.animate({opacity: 0.2}, 700); 
     window.setTimeout(function() { 
      $elem.animate({opacity: 1.0}, 300); 
     }, 1000); 
    }, 1600); 
} 

La valeur de retour vous permettra d'arrêter l'animation si vous voulez comme ceci:

var pulseIntervalId = pulse($('#arrow_id')); 

//some time later... 
window.clearInterval(pulseIntervalId); 

la version ou l'autre contournera le problème de boucle infinie, ce qui permet le rappel d'avoir la référence à l'élément pulsant sans être invoqué prématurément.

+0

wow, je ne pouvais vraiment pas demander pour une réponse plus détaillée! – Jigs

+0

Hah, j'espère que ça marche! GL. – jasongetsdown

3

La réponse de jasongetsdown, bien que techniquement correcte, n'est pas très jQuery-esque. Il a également le problème que si le animate prend un peu plus de temps qu'il le devrait, le window.setTimeout s'en fichera et exécutera une seconde instance en parallèle, ce qui pourrait conduire à toutes sortes de problèmes, il est donc préférable d'attendre la fin du animer l'appel avant d'en déclencher un nouveau.

Voici une autre solution:

$.fn.pulse = function(lowOpacity, highOpacity) { 
    if (isNaN(+lowOpacity)) lowOpacity = 0.2; 
    if (isNaN(+highOpacity)) highOpacity = 1; 
    var that = this; 
    (this) 
     .delay(300) 
     .animate({opacity: lowOpacity}, 700) 
     .delay(300) 
     .animate({opacity: highOpacity}, 300, function() { that.pulse(lowOpacity, highOpacity); }); 
} 

Pour l'utiliser, vous feriez:

$('#elem').pulse(); 

Pour arrêter ce que vous feriez:

$('#elem').stop().clearQueue();