Empêchez l'événement de clic dans jQuery déclenchant plusieurs fois

J'ai créé un commutateur de contenu jQuery . Généralement, ça marche bien, mais il y a un problème. Si vous cliquez sur les liens sur le côté plusieurs fois, plusieurs éléments de contenu deviennent parfois visibles.

Le problème réside probablement dans l'événement Click. Voici le code:

$('#tab-list li a').click( function() { var targetTab = $(this).attr('href'); if ($(targetTab).is(':hidden')) { $('#tab-list li').removeClass('selected'); var targetTabLink = $(this).parents('li').eq(0); $(targetTabLink).addClass('selected'); $('.tab:visible').fadeOut('slow', function() { $(targetTab).fadeIn('slow'); } ); } return false; } ); 

J'ai essayé d'ajouter un verrou à la transition afin que d'autres clics soient ignorés au fur et à mesure de la transition, mais en vain. J'ai également essayé d'empêcher que la transition ne soit déclenchée si quelque chose est déjà animé, en utilisant ce qui suit:

 if ($(':animated')) { // Don't do anything } else { // Do transition } 

Mais il semble toujours penser que les choses sont animées. Des idées sur lesquelles je peux empêcher l'animation d'être déclenchée à plusieurs reprises?

Une idée serait de supprimer l'événement de clic au début de votre fonction, puis d'ajouter l'événement de clic lorsque votre animation a fini, de sorte que les clics pendant la durée n'auraient aucun effet.

Si vous avez la possibilité d'exécuter du code lorsque l'animation est terminée, cela devrait fonctionner.

Ajoutez une variable à utiliser comme un verrou plutôt que comme (: animer).

Sur le clic, vérifiez si le verrou est réglé. Si ce n'est pas le cas, réglez le verrouillage, démarrez le processus, puis relâchez le verrou lorsque le fondu est fini.

 var blockAnimation = false; $('#tab-list li a').click( function() { if(blockAnimation != true){ blockAnimation = true; var targetTab = $(this).attr('href'); if ($(targetTab).is(':hidden')) { $('#tab-list li').removeClass('selected'); var targetTabLink = $(this).parents('li').eq(0); $(targetTabLink).addClass('selected'); $('.tab:visible').fadeOut('slow', function() { $(targetTab).fadeIn('slow', function(){ blockAnimation=false; }); } ); } } return false; } ); 

Eh bien, c'est ainsi que je l'ai fait, et cela a bien fonctionné.

 $(document).ready(function() { $(".clickitey").click(function () { if($("#mdpane:animated").length == 0) { $("#mdpane").slideToggle("slow"); $(".jcrtarrow").toggleClass("arrow-open"); } }); }); 

Cela ne fait pas ce que votre code fait bien sûr, c'est un code de mon site, mais j'aimerais simplement indiquer comment j'ai ignoré les clics qui se produisaient pendant l'animation. Permettez-moi de savoir si cela est inefficace de toute façon. Je vous remercie.

Je me suis retourné avec le code plus tôt et j'ai proposé la modification suivante qui semble fonctionner:

 $('#tab-list li a').click( function() { $('.tab:animated').stop(true, true); var targetTab = $(this).attr('href'); if ($(targetTab).is(':hidden')) { $('#tab-list li').removeClass('selected'); var targetTabLink = $(this).parents('li').eq(0); $(targetTabLink).addClass('selected'); $('.tab:visible').fadeOut('slow', function() { $(targetTab).fadeIn('slow'); } ); } return false; } ); 

Tout ce qui se passe est, lorsqu'un nouvel onglet est cliqué, il apporte immédiatement l'animation actuelle à la fin, puis commence la nouvelle transition.

Une façon serait la suivante:

 $('#tab-list ul li').one( 'click', loadPage ); var loadPage = function(event) { var $this = $(this); $global_just_clicked = $this; var urlToLoad = $this.attr('href'); $('#content-area').load( urlToLoad, pageLoaded ); } $global_just_clicked = null; var pageLoaded() { $global_just_clicked.one( 'click', loadPage ); } 

Comme vous pouvez le voir, cette méthode est lourde de défauts: qu'est-ce qui se passe lorsqu'un autre onglet est cliqué avant que la page actuelle ne se charge? Et si la demande est refusée? Et si c'est une pleine lune?

La réponse est: cette méthode n'est qu'une démonstration rudimentaire. Une mise en œuvre correcte:

  1. Ne contient pas la variable globale $global_just_clicked
  2. Ne pas compter sur .load() . Utiliserait .ajax() , et manipulerait l'annulation de la demande, en cliquant sur d'autres onglets, etc.

REMARQUE: Dans la plupart des cas, vous ne devez pas prendre cette approche ronde. Je suis sûr que vous pouvez remédier à votre code de telle sorte que les multiples clics sur le même onglet n'affectent pas le résultat final.

Jrh.

Une façon de le faire pour utiliser la propriété timeStamp de l'événement comme ceci à l'intervalle entre plusieurs clics:

 var a = $("a"), stopClick = 0; a.on("click", function(e) { if(e.timeStamp - stopClick > 300) { // give 300ms gap between clicks // logic here stopClick = e.timeStamp; // new timestamp given } });