J'essaie d'écrire un jeu de vidéo poker en Javascript comme un moyen d'en descendre les bases, et j'ai rencontré un problème où les gestionnaires d'événements click jQuery se déclenchent plusieurs fois.
Ils sont attachés aux boutons pour placer un pari, et cela fonctionne très bien pour placer un pari sur la première main pendant un jeu (tirer 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 pressé (donc le montant correct est parié deux fois 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 main depuis le début du jeu: 1, 2, 4 , 7, 11, 16, 22, 29, 37, 46, ce qui semble être n (n + 1) / 2 + 1 pour tout ce qui vaut - et je n'étais pas assez intelligent pour le comprendre, j'ai utilisé OEIS . :)
Voici la fonction avec les gestionnaires d'événements click qui agissent; j'espère que c'est facile à comprendre (faites le moi savoir si non, je veux aussi m'améliorer):
/** 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 laissez-moi savoir si vous avez des idées ou des suggestions, ou si la solution à mon problème est similaire à une solution à un autre problème ici (j'ai regardé de nombreux sujets de même titre et je n'ai pas eu de chance de trouver une solution qui pourrait fonctionner pour moi).
la source
var amount = parseInt(this.id.replace(/[^\d]/g,''),10);
Et si vous comptez utiliser plusieurs fois la même propriété d'un élément , mettez-la en cache . La recherche coûte cher.Réponses:
Pour vous assurer qu'une action de clic uniquement une fois, utilisez ceci:
la source
.unbind()
est obsolète et vous devez utiliser la.off()
méthode à la place. Appelez simplement.off()
juste avant d'appeler.on()
.Cela supprimera tous les gestionnaires d'événements:
Pour supprimer uniquement les gestionnaires d'événements «clic» enregistrés:
la source
.une()
Une meilleure option serait
.one()
:Dans le cas de plusieurs classes et chaque classe doit être cliquée une fois,
la source
onclick
événements au même élément , mais dans différents endroits cela n'affectera le reste, alors queunbind()
etoff()
va simplement détruire d' autresonclick
s vous remercie encore une foisSi vous trouvez que .off () .unbind () ou .stopPropagation () ne résout toujours pas votre problème spécifique, essayez d'utiliser .stopImmediatePropagation () Fonctionne très bien dans les situations où vous voulez juste que votre événement soit géré sans bouillonnement et sans effectuer tous les autres événements déjà traités. Quelque chose comme:
fait l'affaire!
la source
Si vous appelez cette fonction à chaque "clic", cela ajoute une autre paire de gestionnaires à chaque appel.
Ajouter des gestionnaires avec jQuery n'est pas comme définir la valeur de l'attribut "onclick". On peut ajouter autant de gestionnaires que l'on désire.
la source
un événement se déclenche plusieurs fois lorsqu'il est enregistré plusieurs fois (même s'il concerne le même gestionnaire).
Par exemple,
$("ctrl").on('click', somefunction)
si ce morceau de code est exécuté à chaque fois que la page est partiellement rafraîchie, l'événement est également enregistré à chaque fois. Par conséquent, même si le bouton Ctrl n'est cliqué qu'une seule fois, il peut exécuter plusieurs fois "une fonction" - le nombre de fois qu'il dépendra du nombre de fois qu'il a été enregistré.cela est vrai pour tout événement enregistré en javascript.
Solution:
assurez-vous d'appeler "on" une seule fois.
et pour une raison quelconque, si vous ne pouvez pas contrôler l'architecture, procédez comme suit:
$("ctrl").off('click'); $("ctrl").on('click', somefunction);
la source
J'ai eu un problème à cause du balisage.
HTML:
jQuery
Vous remarquez que j'ai la même classe 'myclass' deux fois en html, donc il appelle click pour chaque instance de div.
la source
La meilleure option serait d'utiliser off
la source
Tout ce qui concerne .on () et .one () est génial, et jquery est génial.
Mais parfois, vous voulez qu'il soit un peu plus évident que l'utilisateur n'est pas autorisé à cliquer, et dans ces cas, vous pouvez faire quelque chose comme ceci:
et votre bouton ressemblerait à:
la source
Cela se produit car 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 attachés en utilisant la
.die()
méthode.Et puis attachez votre écouteur de méthode.
Donc,
devrait être:
la source
Nous devons
stopPropagation()
Afin d'éviter les clics déclencheurs trop d'événements.Il empêche l'événement de se propager dans l'arborescence DOM, empêchant les gestionnaires parents d'être notifiés de l'événement. Cette méthode n'accepte aucun argument.
Nous pouvons utiliser
event.isPropagationStopped()
pour déterminer si cette méthode a déjà été appelée (sur cet objet événement).Cette méthode fonctionne également pour les é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.
la source
Dans mon cas, j'utilisais «délégué», donc aucune de ces solutions n'a fonctionné. Je pense que c'est le bouton apparaissant plusieurs fois via les appels ajax qui a causé le problème des clics multiples. Les solutions utilisaient un délai d'attente, donc seul le dernier clic est reconnu:
la source
Documents:
http://api.jquery.com/one/
la source
la source
.un ne se déclenche qu'une seule fois pendant la durée de vie de la page
Donc, si vous voulez faire une validation, ce n'est pas la bonne solution, car lorsque vous ne quittez pas la page après la validation, vous ne revenez jamais. Mieux utiliser
la source
Lorsque je traite ce problème, j'utilise toujours:
De cette façon, je délie et ressaisis du même coup.
la source
https://jsfiddle.net/0vgchj9n/1/
Pour vous assurer que l'événement ne se déclenche toujours qu'une seule fois, vous pouvez utiliser Jquery .one (). JQuery one garantit que votre gestionnaire d'événements n'a appelé qu'une seule fois. En outre, vous pouvez souscrire votre gestionnaire d'événements avec un pour autoriser d'autres clics lorsque vous avez terminé le traitement de l'opération de clic en cours.
…
la source
Essayez de cette façon:
la source
Dans mon cas, l'événement onclick se déclenchait plusieurs fois car j'avais fait un gestionnaire d'événements générique
changé en
et doivent également créer des gestionnaires distincts pour les clics statiques et dynamiques, pour les clics statiques sur les onglets
la source
Dans mon cas, j'avais chargé le même
*.js
fichier sur la page deux fois dans une<script>
balise, donc les deux fichiers attachaient des gestionnaires d'événements à l'élément. J'ai supprimé la déclaration en double et cela a résolu le problème.la source
Une autre solution que j'ai trouvée était la suivante, si vous avez plusieurs classes et que vous traitez des boutons radio en cliquant sur l'étiquette.
la source
J'avais ce problème avec un lien généré dynamiquement:
$(document).on('click', '#mylink', function({...do stuff...});
J'ai trouvé le remplacement
document
par'body'
résolu le problème pour moi:$('body').on('click', '#mylink', function({...do stuff...});
la source
Unbind () fonctionne, mais cela pourrait entraîner d'autres problèmes à l'avenir. Le gestionnaire se déclenche plusieurs fois lorsqu'il se trouve à l'intérieur d'un autre gestionnaire, alors laissez votre gestionnaire à l'extérieur et si vous voulez les valeurs du gestionnaire qui avaient été imbriquées, affectez-les à une variable globale qui sera accessible au gestionnaire.
la source
Au cas où cela fonctionnerait bien
la source
Le code ci-dessous a fonctionné pour moi dans mon application de chat pour gérer plusieurs événements déclenchant un clic de souris plus d'une fois.
if (!e.originalEvent.detail || e.originalEvent.detail == 1) { // Your code logic }
la source