109 votes

Le callback de .animate() est appelé deux fois par jquery

Depuis que j'ai ajouté quelques scrollTop -Certaines parties de mon rappel sont appelées deux fois :

$('html, body').animate({scrollTop: '0px'}, 300,function() {
    $('#content').load(window.location.href, postdata, function() {                 
        $('#step2').addClass('stepactive').hide().fadeIn(700, function() {
            $('#content').show('slide',800);                    
        });
    });
});

Il semble seulement répéter le .show() En tout cas, je n'ai pas l'impression que la load() ou le .fadeIn() être appelé une seconde fois aussi. Le site .show() est répétée dès qu'elle s'est terminée pour la première fois. En réglant la vitesse d'animation de scrollTop sur 0 n'a pas aidé d'ailleurs !

Je suppose que cela a quelque chose à voir avec l'animation-queue, mais je n'arrive pas à trouver une solution de contournement et surtout pourquoi c'est en train de se produire.

177voto

Kevin B Points 57721

Pour obtenir un rappel unique pour l'achèvement des animations de plusieurs éléments, utilisez des objets différés.

$(".myClass").animate({
  marginLeft: "30em"
}).promise().done(function(){
  alert("Done animating");
});

Voir l'API de jQuery pour une description détaillée de l'API. Promesse et Objets différés .

0 votes

C'est un problème résolu pour ce que nous voulons faire à la fin de l'animation, mais le problème du double appel et j'ai obtenu +1 pour cela, mais je ne sais pas si le processus d'animation est appelé deux fois ou pas !

1 votes

Le processus d'animation n'est pas appelé deux fois, le callback est appelé une fois pour chaque élément sélectionné. Ainsi, si vous sélectionnez 8 éléments de liste et les animez vers la gauche, le callback sera exécuté 8 fois. Ma solution vous donne un seul callback lorsque les 8 éléments sont terminés.

0 votes

@KevinB, bonne solution, et cela m'a aidé à résoudre mes propres problèmes de callback également. Merci.

172voto

T.J. Crowder Points 285826

animate appelle son rappel une fois pour chaque élément dans l'ensemble que vous appelez animate sur :

Si elle est fournie, la start , step , progress , complete , done , fail et always sont appelés sur une base par élément ...

Puisque vous animez deux éléments (le html et l'élément body ), vous obtenez deux rappels. (Pour ceux qui se demandent pourquoi l'OP anime deux éléments, c'est parce que l'animation fonctionne sur body sur certains navigateurs mais sur html sur d'autres navigateurs).

Pour obtenir un simple lorsque l'animation est terminée, la fonction animate La documentation vous conseille d'utiliser l'option promise pour obtenir une promesse pour la file d'attente des animations, puis en utilisant la méthode then pour mettre en file d'attente le callback :

$("html, body").animate(/*...*/)
    .promise().then(function() {
        // Animation complete
    });

(Note : Kevin B a signalé ce point dans sa réponse lorsque la question a été posée pour la première fois. Je ne l'ai fait que quatre ans plus tard, quand j'ai remarqué qu'elle manquait, je l'ai ajoutée et... j'ai vu la réponse de Kevin. Veuillez donner à sa réponse l'amour qu'elle mérite. Je me suis dit que comme c'est la réponse acceptée, je devais la laisser).

Voici un exemple montrant à la fois les rappels des éléments individuels et le rappel global d'achèvement :

jQuery(function($) {

  $("#one, #two").animate({
    marginLeft: "30em"
  }, function() {
    // Called per element
    display("Done animating " + this.id);
  }).promise().then(function() {
    // Called when the animation in total is complete
    display("Done with animation");
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }
});

<div id="one">I'm one</div>
<div id="two">I'm two</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

2 votes

Oui, c'était la raison et en fait je ne me rappelle pas pourquoi j'ai écrit. html, body . Il est temps de rallumer mon cerveau. Merci

21 votes

Probablement parce qu'animer seulement html ne fonctionnera pas dans Webkit, et seulement body ne fonctionnera pas dans Opera. L'utilisation des deux assure que cela fonctionne toujours, mais déclenchera le callback deux fois dans Firefox. (J'ai peut-être mal compris les navigateurs...)

2 votes

html est nécessaire pour IE, et le callback se déclenchera deux fois pour la plupart des autres navigateurs. J'essaie de trouver une solution au même problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X