IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

jQuery Discussion :

callback d'animate appelé 2x ?


Sujet :

jQuery

  1. #1
    Membre confirmé
    Avatar de Amnesiak
    Profil pro
    Inscrit en
    Août 2002
    Messages
    137
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2002
    Messages : 137
    Par défaut callback d'animate appelé 2x ?
    Bonsoir,

    J'ai réussi à isoler dans l'exemple ci-dessous un phénomène que je n'arrive pas à expliquer. Il s'agit d'une animation d'un élément pour laquelle la fonction callback semble se lancer 2x. Pour bien comprendre ce que je cherche à réaliser, j'ai réduit le problème en un exemple simpliste de chat/souris :

    Au chargement de la page, 1 petit div (qui représente une souris) se déplace aléatoirement de gauche à droite grâce à une animation infinie. Idéalement il doit y avoir plusieurs souris, mais pour simplifier je n'en affiche qu'une.
    Lors du clic sur un bouton, 1 autre div (le chat) commence à se déplacer. Une fois l'animation du chat terminée, je décide d'immobiliser les souris.

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    <script type="text/javascript">
    $(document).ready(function(){
     
        // animation infinie d'une souris
        function animateMouse(id)
        {
            var x = Math.floor(Math.random()*200);
            $("#"+id).animate({"margin-left":x},400,"linear",function(){
                animateMouse(id);
            });
        }
     
        // démarre l'animation de la souris
        animateMouse("mouse1");
     
        $("#button").click(function(){
     
            console.log("click!");
     
            // démarre l'animation du chat
            $("#cat").animate({"margin-left":200},200,"linear",function(){
     
                console.log("cat stopped");
     
                // immobilise toutes les souris
                $(".mouse").each(function(i,e){
                    console.log("stopping mouse "+$(e).attr("id"));
                    $(e).stop();
                });
            });
        });
    });
    </script>
     
    <input type="button" id="button" value="START" />
    <div id="cat"></div>
    <div id="mouse1" class="mouse"></div>
    <div id="mouse2" class="mouse"></div>
    Malgré que ce soit simple, il semble que le callback de l'animation du chat soit exécuté 2x, comme le montre le résultat suivant. Par contre j'ai l'impression que ce n'est pas systématique... on dirait que parfois ça se déroule correctement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    click!
    cat stopped
    stopping mouse mouse1
    cat stopped
    stopping mouse mouse1
    Comble de l'étrangeté, si je commente la ligne $(e).stop(), l'animation se déroule toujours correctement. J'avoue ne pas y comprendre grand chose.

    Quelqu'un aurait une explication ? Peut-être que je m'y prend mal pour la boucle infinie ? Merci pour vos idées, toute piste est bonne à prendre.

    PS : J'ai testé sous Firefox 7.0.1 avec jQuery1.6.4, 1.6.3 et 1.6.2

  2. #2
    Membre confirmé
    Avatar de Amnesiak
    Profil pro
    Inscrit en
    Août 2002
    Messages
    137
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2002
    Messages : 137
    Par défaut
    Bonjour, je ne sais pas si ma description du problème est assez compréhensible. Pour ceux qui souhaiteraient tester par l'exemple, je l'ai mis à disposition ici : http://www.geoffray.be/public/demo/anim_jquery.html

    Merci d'avance

  3. #3
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2011
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Philippines

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2011
    Messages : 89
    Par défaut
    Sous Chrome chez moi le log n'a lieu qu'une seule fois. Tu utilises quel navigateur ?

  4. #4
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 659
    Billets dans le blog
    1
    Par défaut
    Je ne vois rien d'anormal sous ffx ...
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  5. #5
    Membre confirmé
    Avatar de Amnesiak
    Profil pro
    Inscrit en
    Août 2002
    Messages
    137
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2002
    Messages : 137
    Par défaut
    Le cas ne se produit pas à chaque fois... il faut recharger la page puis cliquer sur le bouton. Parfois le log affiche 2x "cat stopped" alors que ça ne devrait apparaître qu'une seule fois.

    Parfois le callback est appelé 2x :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    click!
    cat stopped
    stopping mouse mouse1
    cat stopped
    stopping mouse mouse1
    Et parfois une seule fois, ce qui est normal:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    click!
    cat stopped
    stopping mouse mouse1
    Après quelques essais, j'ai pu reproduire le problème sous Firefox 7.0.1 (XP et Seven), Chrome 14.0.835 (XP), Safari 5.0.5 (XP), ainsi qu'Opera 11.11 (XP)

  6. #6
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut
    Bonsoir

    Je suggère de tester : $(e).stop(true, true);

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  7. #7
    Membre confirmé
    Avatar de Amnesiak
    Profil pro
    Inscrit en
    Août 2002
    Messages
    137
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2002
    Messages : 137
    Par défaut
    Bonjour Daniel, merci pour ta suggestion mais elle n'y change rien malheureusement. J'ai même essayé toutes les combinaisons de paramètres dans la méthode stop()

    Honnêtement, je ne vois pas où je m'y prends mal... mais avant d'imaginer l'hypothèse d'un bug dans la lib, je préfère me dire qu'il doit y avoir une subtilité qui m'échappe... mais ou ?

    PS : Est-ce que le problème indiqué se manifeste aussi chez d'autres personnes, ou suis-je le seul ?

  8. #8
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut
    Bonjour

    Le problème existe bien, c'est une bogue de la version 1.6.4 qui semble avoir été corrigée dans la version 1.7 b1. Attention cette version Beta à d'autres bogues surtout avec UI.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    <!doctype html>
    <html lang="fr">
    <head>
    	<meta charset="utf-8">
    	<meta name="Author" content="Daniel Hagnoul">
    	<title>Forum jQuery</title>
    	<style>
    		#cat {
    			width:60px;
    			height:20px;
    			background-color:black;
    		}
    		.mouse {
    			width:20px;
    			height:20px;
    			background-color:#c8c8c8;
    		}
    	</style>
    </head>
    <body>	
    	<input type="button" id="button" value="START" />
    	<div id="cat"></div>
    	<div id="mouse1" class="mouse"></div>
    	<!-- <script charset="utf-8" src="http://code.jquery.com/jquery-1.6.4.min.js"></script> -->
    	<script charset="utf-8" src="http://code.jquery.com/jquery-1.7b1.min.js"></script>
    	<script>
    		$(function(){
    			function animateMouse(id)
    			{
    				var x = Math.floor(Math.random()*200);
    				$("#"+id).animate({"margin-left":x},400,"linear",function(){
    					animateMouse(id);
    				});
    			}
     
    			animateMouse("mouse1");
     
    			$("#button").click(function(){
    				console.log("click!");
    				$("#cat").animate({"margin-left":200},200,"linear",function(){
    					console.log("cat stopped");
    					$(".mouse").each(function(i,e){
    						console.log("stopping mouse "+$(e).attr("id"));
    						$(e).stop();
    					});
    				});
    			});
    		});
    	</script>
    </body>  
    </html>

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  9. #9
    Membre confirmé
    Avatar de Amnesiak
    Profil pro
    Inscrit en
    Août 2002
    Messages
    137
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2002
    Messages : 137
    Par défaut
    Merci Daniel pour cette nouvelle ! Aurais-tu par hasard plus d'infos sur le bug en question car je ne le trouve pas dans le changelog de la 1.7 http://blog.jquery.com/2011/09/28/jq...ta-1-released/
    Il serait en effet utile de savoir dans quelles conditions le cas se produit, car si n'importe quel callback est susceptible d'être démarré plusieurs fois, c'est assez problématique !

    En attendant une release stable, j'ai choisi d'opter pour un "hack" maison...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            $("#cat").data("anim",true).animate({"margin-left":200},200,"linear",function(){
                if ($(this).data("anim")) {
                    $(this).data("anim",false);
                    console.log("cat stopped");
     
                    // ...
                }
            });

  10. #10
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut
    Bonsoir

    Avec 1.6.4, en utilisant une vraie fonction plutôt qu'une fonction anonyme comme fonction de rappel, je ne vois plus la bogue causée par la méthode stop (voir la liste des corrections de bogue de 1.7b1).

    Blog jQuery, extrait du "changelog" de 1.7b1
    Effects

    #5684: Effects: exception in animation callback causes endless loop
    #6150: .stop sometimes doesn’t clear .delay
    #6641: Calling stop() within animation finished callback causes other animations to freeze
    #8685: Animations should keep track of animation state in order to properly address stacked animations
    #9280: Allow multiple effect queues for animate()
    #9548: animate does not work with fill-opacity css property for svg elements
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    <!doctype html>
    <html lang="fr">
    <head>
    	<meta charset="utf-8">
    	<meta name="Author" content="Daniel Hagnoul">
    	<title>Forum jQuery</title>
    	<style>
    		#cat {
    			width:60px;
    			height:20px;
    			background-color:black;
    		}
    		.mouse {
    			width:20px;
    			height:20px;
    			background-color:#c8c8c8;
    		}
    	</style>
    </head>
    <body>	
    	<input type="button" id="button" value="START" />
    	<div id="cat"></div>
    	<div id="mouse1" class="mouse"></div>
    	<script charset="utf-8" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
    	<!-- <script charset="utf-8" src="http://code.jquery.com/jquery-1.7b1.min.js"></script> -->
    	<script>
    		$(function(){
    			function animateMouse(id)
    			{
    				var x = Math.floor(Math.random()*200);
    				$("#"+id).animate({"margin-left":x},400,"linear",function(){
    					animateMouse(id);
    				});
    			}
     
    			function animateFnRap(){
    				console.log("cat stopped");
     
    				$(".mouse").each(function(i,e){
    					console.log("stopping mouse "+$(e).attr("id"));
    					$(e).stop();
    				});
    			}
     
    			animateMouse("mouse1");
     
    			$("#button").click(function(){
    				console.log("click!");
    				$("#cat").animate({"margin-left":200},200,"linear", animateFnRap);
    			});
    		});
    	</script>
    </body>  
    </html>

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

Discussions similaires

  1. [Threadpool] Passage de callback différente à chaque appel
    Par Tarteaututo dans le forum Threads & Processus
    Réponses: 6
    Dernier message: 17/04/2013, 12h46
  2. appel d'une page html dans animation flash
    Par dalloul dans le forum Flash
    Réponses: 4
    Dernier message: 01/12/2006, 12h47
  3. [FLASH 8] Faire appel à un fichier animé de type .GIF
    Par °°° Zen-Spirit °°° dans le forum Flash
    Réponses: 3
    Dernier message: 28/07/2006, 10h53
  4. Réponses: 8
    Dernier message: 09/01/2006, 16h58
  5. Réponses: 3
    Dernier message: 26/02/2005, 09h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo