JQuery clique les événements en tirant plusieurs fois

J'essaie d'écrire un jeu de vidéo poker en version JavaScript afin d'en tirer les bases et j'ai rencontré un problème où les gestionnaires d'événements de clic jQuery tirent plusieurs fois.

Ils sont attachés aux boutons pour placer un pari, et ça marche bien pour placer un pari en première main pendant un match (tirant une seule fois); Mais en pariant pour la seconde main, il déclenche l'événement de clic deux fois chaque fois qu'un bouton de pari ou de pari est appuyé (alors deux fois le montant correct est pari pour chaque pression). Dans l'ensemble, il suit ce modèle pour le nombre de fois que l'événement de clic est déclenché lorsque vous appuyez une fois sur un bouton de pari où le ième terme de la séquence est pour le pari de la ième depuis le début du jeu: 1, 2, 4 , 7, 11, 16, 22, 29, 37, 46, qui semble être n (n + 1) / 2 + 1 pour tout ce qui vaut – et je n'étais pas assez intelligent pour comprendre, j'ai utilisé OEIS . 🙂

Voici la fonction avec les gestionnaires d'événements de clic qui agissent; Je l'espère, c'est facile à comprendre (laissez-moi savoir, sinon, je veux améliorer moi aussi):

/** The following function keeps track of bet buttons that are pressed, until place button is pressed to place bet. **/ function pushingBetButtons() { $("#money").text("Money left: $" + player.money); // displays money player has left $(".bet").click(function() { var amount = 0; // holds the amount of money the player bet on this click if($(this).attr("id") == "bet1") { // the player just bet $1 amount = 1; } else if($(this).attr("id") == "bet5") { // etc. amount = 5; } else if($(this).attr("id") == "bet25") { amount = 25; } else if($(this).attr("id") == "bet100") { amount = 100; } else if($(this).attr("id") == "bet500") { amount = 500; } else if($(this).attr("id") == "bet1000") { amount = 1000; } if(player.money >= amount) { // check whether the player has this much to bet player.bet += amount; // add what was just bet by clicking that button to the total bet on this hand player.money -= amount; // and, of course, subtract it from player's current pot $("#money").text("Money left: $" + player.money); // then redisplay what the player has left } else { alert("You don't have $" + amount + " to bet."); } }); $("#place").click(function() { if(player.bet == 0) { // player didn't bet anything on this hand alert("Please place a bet first."); } else { $("#card_para").css("display", "block"); // now show the cards $(".card").bind("click", cardClicked); // and set up the event handler for the cards $("#bet_buttons_para").css("display", "none"); // hide the bet buttons and place bet button $("#redraw").css("display", "block"); // and reshow the button for redrawing the hand player.bet = 0; // reset the bet for betting on the next hand drawNewHand(); // draw the cards } }); } 

S'il vous plaît, faites-moi savoir si vous avez des idées ou des suggestions, ou si la solution à mon problème ressemble à une solution à un autre problème ici (j'ai examiné plusieurs rubriques intitulées de manière similaire et j'ai eu de la chance de trouver une solution qui pourrait fonctionner pour moi).

    Pour vous assurer que les actions d'un clic uniquement utilisent ceci:

     $(".bet").unbind().click(function() { //Stuff }); 

    .unbind() est obsolète et vous devez utiliser la méthode .off() . Appelez simplement .off() juste avant d'appeler .on() .

    Cela supprimera tous les gestionnaires d'événements:

     $(element).off().on('click', function() { // function body }); 

    Pour supprimer uniquement les gestionnaires d'événements enregistrés «cliquer»:

     $(element).off('click').on('click', function() { // function body }); 

    .un()

    Une meilleure option serait .one() :

    Le gestionnaire est exécuté au plus une fois par élément par type d'événement.

     $(".bet").one('click',function() { //Your function }); 

    Dans le cas de plusieurs classes et chaque classe doit être cliquée une fois,

     $(".bet").on('click',function() { //Your function $(this).off('click'); //or $(this).unbind() }); 

    Si vous trouvez que .off () .unbind () ou .stopPropagation () ne résout pas encore votre problème spécifique, essayez d'utiliser .stopImmediatePropagation () Fonctionne bien lorsque vous souhaitez que votre événement soit traité sans bouillonnement et sans Effectuant tout autre événement déjà traité. Quelque chose comme:

     $(".bet").click(function(event) { event.stopImmediatePropagation(); //Do Stuff }); 

    Fait l'affaire!

    Si vous appelez cette fonction sur chaque «clic», vous ajoutez une autre paire de gestionnaires à chaque appel.

    L'ajout de gestionnaires avec jQuery n'est pas comme configurer la valeur de l'attribut "onclick". On peut ajouter autant de gestionnaires que l'on le désire.

    Cela se produit en raison de l'événement particulier est lié plusieurs fois au même élément.

    La solution qui a fonctionné pour moi est:

    Tuez tous les événements liés en utilisant la méthode .die() .

    Ensuite, connectez votre auditeur de méthode.

    Ainsi,

     $('.arrow').click(function() { // FUNCTION BODY HERE } 

    devrait être:

     $('.arrow').die("click") $('.arrow').click(function() { // FUNCTION BODY HERE } 

    C'est un vieux problème, mais je l'ai fait face aujourd'hui, et je pense que ma réponse aidera le futur demandeur de défis similaires.

    Il est exécuté à plusieurs reprises, car la fonction "on ('click', somefunction)" est appelée plusieurs fois et donc elle est reliée à plusieurs reprises – pour résister de façon permanente, vous devez vous assurer que la fonction "on" fonctionne dans un tel Placez qu'il ne sera exécuté qu'une seule fois. Après quoi, sur l'événement de clic de souris, la fonction sera déclenchée une seule fois.

    Par exemple si je met "on ('click', somefunction)" dans un endroit où il sera chargé deux fois, puis à chaque clic – "somefunction" sera déclenché deux fois.

    Dans une séquence logique correcte, la fonction "off" ne doit être utilisée que lorsque vous avez vraiment l'intention de débrancher les événements. Pour l'utiliser pour cacher les erreurs logiques causées par le double chargement de la fonction "on", n'est pas une bonne approche même si cela semble fonctionner.

    Nous devons stopPropagation() afin d'éviter les déclencheurs déclenche l'événement trop souvent.

     $(this).find('#cameraImageView').on('click', function(evt) { evt.stopPropagation(); console.log("Camera click event."); }); 

    Il empêche l'événement de faire bouillir l'arborescence DOM, empêchant tout gestionnaire parent d'être informé de l'événement. Cette méthode n'accepte aucun argument.

    Nous pouvons utiliser event.isPropagationStopped() pour déterminer si cette méthode a été appelée (sur cet objet d'événement).

    Cette méthode fonctionne également pour des événements personnalisés déclenchés avec trigger (). Notez que cela n'empêchera pas les autres gestionnaires du même élément de s'exécuter.

    J'ai eu un problème à cause du balisage.

    HTML:

     <div class="myclass"> <div class="inner"> <div class="myclass"> <a href="#">Click Me</a> </div> </div> </div> 

    JQuery

     $('.myclass').on('click', 'a', function(event) { ... } ); 

    Vous remarquez que j'ai la même classe 'myclass' deux fois en html, alors il appelle cliquez pour chaque instance de div.

    La meilleure option serait utilisée

     <script> function flash() { $("div").show().fadeOut("slow"); } $("#bind").click(function() { $( "body" ) .on("click", "#theone", flash) .find("#theone") .text("Can Click!"); }); $("#unbind").click(function() { $("body") .off("click", "#theone", flash) .find("#theone") .text("Does nothing..."); }); </script> 

    Toutes les choses sur .on () et .one () sont formidables, et jquery est génial.

    Mais parfois, vous voulez qu'il soit un peu plus évident que l'utilisateur n'a pas le droit de cliquer, et dans ces cas, vous pouvez faire quelque chose comme ceci:

     function funName(){ $("#orderButton").prop("disabled", true); // do a bunch of stuff // and now that you're all done setTimeout(function(){ $("#orderButton").prop("disabled",false); $("#orderButton").blur(); }, 3000); } 

    Et votre bouton ressemblerait à:

     <button onclick='funName()'>Click here</button> 
     $(element).click(function (e) { if(e.timeStamp !== 0) // This will prevent event triggering more then once { //do your stuff } } 

    https://jsfiddle.net/0vgchj9n/1/

    Pour vous assurer que l'événement ne se déclenche que d'une seule fois, vous pouvez utiliser Jquery .one (). JQuery One garantit que votre gestionnaire d'événements ne soit appelé qu'une seule fois. En outre, vous pouvez souscrire votre gestionnaire d'événements avec un seul pour permettre d'autres clics lorsque vous avez terminé le traitement de l'opération de clic actuel.

     <div id="testDiv"> <button class="testClass">Test Button</button> </div> 

     var subscribeClickEvent = function() {$("#testDiv").one("click", ".testClass", clickHandler);}; function clickHandler() { //... perform the tasks alert("you clicked the button"); //... subscribe the click handler again when the processing of current click operation is complete subscribeClickEvent(); } subscribeClickEvent();