2009-08-31 7 views
2

J'utilise jquery et ce que je fais lie la méthode toggle à un certain nombre de boutons sur une page Web. Il ressemble à ceciLe meilleur moyen d'empêcher une fonction javascript de s'exécuter alors qu'il est déjà ou un autre est?

$('.button').toggle(function(){ 
    // first function 
}, function(){ 
    // second function 
}); 

Cependant, il existe des animations dans ces deux fonctions. Un utilisateur peut donc cliquer sur le bouton pendant l'exécution de la première ou de la deuxième fonction. Et cela chamboule l'ordre des éléments HTML et peut les faire passer à la fin de la page. Parce que essentiellement ce que ces fonctions font est de déplacer un élément à la fin sur le premier clic, et sur l'autre cliquez le déplacer où il était à l'origine.

Bien sûr, il est difficile de cliquer sur le bouton une fois qu'il se déplace sur la page. Mais c'est possible.

Répondre

0

Vous semblez plus heureux de mettre en œuvre votre propre basculement. Toggle ne fonctionne vraiment que pour les cas avec 0 logique supplémentaire.

$('.button').click( 
function() { 
    if($(self).is(":animated") { 
    return false; 
    } 
    if($(self).is(".rolledup")) { 
    self.apply(roll_window_down);  
    } else { 
    self.apply(roll_window_up);  
    } 
}); 



function roll_window_up() { 
    $(self).addClass('rolledup'); 

    // first function  
} 

function roll_window_down() { 
    $(self).removeClass('rolledup'); 
    // first function  
} 
+0

Je pense que c'est ce que je vais faire. – fent

5

Vous pourriez utiliser un drapeau. Définissez un indicateur 'isAnimating' sur true lorsqu'une animation commence, et false lorsqu'elle se termine. Toute animation suivante ne peut continuer que si cette valeur est false.

Vous pouvez également éventuellement vérifier si le :animated selector s'applique au propriétaire de l'événement. Et basez vos décisions sur cela.

+0

Est-ce que cela pourrait fonctionner avec toggle()? Si j'arrête la première exécution parce qu'il y a une fonction d'animation deux, la prochaine fois que l'utilisateur cliquera sur le bouton, il ira à la deuxième fonction. – fent

+0

Ce que je suggère, c'est de mettre une «if-statement» au début de chaque fonction.Si 'isAnimating' est vrai, vous quittez la fonction. Si c'est faux, vous continuez avec la fonction. Est-ce que ce n'est pas ce que vous cherchez? – Sampson

+0

Je sais ce que tu veux dire. Je me demandais juste si je pouvais le faire tout en gardant la fonction toggle() là. Mais je vais devoir m'en débarrasser et utiliser le mien pour décider quelle fonction utiliser. – fent

3

Vous pouvez utiliser un bool comme un semi-côtier .. Évidemment, ce n'est pas sûr, mais le javascript ne supporte pas vraiment le verrouillage, donc vous pourriez facilement avoir des blocages et/ou conditions de course avec cette approche, mais travailler 99,9% des temps :)

0

vous devez placer les deux fonctions que vous passez à basculer dans un contexte dans lequel vous pouvez tenir un drapeau pour contrôler l'entrée de la fonction: -

(function() { 
    var toggling = false; 
    $('.button').toggle(function(){ 
    if (!toggling) { 
     toggling = true;   
     // first function 
     toggling = false; 
    } else { 
     // whatever you want to happen if re-entrance attempted 
    } 
    }, function(){ 
    if (!toggling) { 
     toggling = true;   
     // second function 
     toggling = false; 
    } else { 
     // whatever you want to happen if re-entrance attempted 
    } 
    }) 
)(); 

NB Ceci sérialise tous les bascule des éléments qui ont la classe .button. IOW il n'y a qu'un seul drapeau toggling pour tous les boutons. Si vous souhaitez que chaque bouton ait son propre indicateur de basculement: -

$('.button').each(function() { 
    var toggling = false; 
    $(this).toggle(function(){ 
    if (!toggling) { 
     toggling = true;   
     // first function 
     toggling = false; 
    } else { 
     // whatever you want to happen if re-entrance attempted 
    } 
    }, function(){ 
    if (!toggling) { 
     toggling = true;   
     // second function 
     toggling = false; 
    } else { 
     // whatever you want to happen if re-entrance attempted 
    } 
    }); 
); 
+0

Merci. Bien que la logique soit un peu fausse. Si une utilisation clique sur le bouton puis le clique de nouveau pendant l'animation, la deuxième fonction de bascule se déclenche mais rien ne se produit à cause du if (! Toggling). Ensuite, la prochaine fois qu'ils cliquent dessus, le bouton sera au bas de la page mais la première fonction se déclenchera. Merci cependant, tout ce que j'ai à faire est de mettre l'instruction if avant toggle(). – fent

+0

@Roly: Il n'était pas clair à partir de votre question quelle était votre logique mais l'exemple est conçu pour démontrer comment vous pourriez créer les contextes appropriés pour tenir le drapeau nécessaire. J'étais sûr que vous pourriez donner l'exemple à votre logique spécifique au besoin. – AnthonyWJones

0

Vous avez besoin d'une file d'attente. Vous pouvez construire une avec une variable sémaphores, mais jQuery fournit déjà un, alors peut-être que vous voulez utiliser:

$('.button').toggle(function() { 
    $(document).queue("foo", function() { 
    ... 
    }); 
}, function() { 
    $(document).queue("foo", function() { 
    ... 
    }); 
}); 

jQuery utilise normalement la file d'attente « fx » sérialiser animations, mais vous pouvez utiliser cette « foo » file d'attente pour ce que vous voulez.

La file d'attente peut être placée sur n'importe quel objet, alors peut-être que vous voulez le placer sur le conteneur contenant tous les objets . Vous ne pouvez pas le mettre sur le bouton (ce) eux-mêmes, ou vous serez de retour là où vous êtes maintenant.

Une fois que vous avez fait cela, tout ce que vous avez vraiment besoin de faire est d'abandonner une animation. Cela peut être fait en vidant expressément la file d'attente "fx", ou vous pouvez utiliser $('.button').stop(); pour arrêter toutes les anciennes animations.

Questions connexes