Ich versuche, ein Video-Pokerspiel in Javascript zu schreiben, um die Grundlagen zu erläutern, und bin auf ein Problem gestoßen, bei dem die Handler für jQuery-Klickereignisse mehrmals ausgelöst werden.
Sie sind an Schaltflächen zum Platzieren einer Wette angebracht und eignen sich gut zum Platzieren einer Wette aus erster Hand während eines Spiels (nur einmal abfeuern). Beim Wetten für die zweite Hand wird das Klickereignis jedoch jedes Mal zweimal ausgelöst, wenn eine Wette oder eine Platzierungswette gedrückt wird (also wird bei jedem Drücken der doppelte richtige Betrag gesetzt). Insgesamt folgt es diesem Muster für die Häufigkeit, mit der das Klickereignis ausgelöst wird, wenn einmal eine Wetttaste gedrückt wird - wobei der i-te Term der Sequenz für das Wetten der i-ten Hand vom Beginn des Spiels an gilt: 1, 2, 4 , 7, 11, 16, 22, 29, 37, 46, was für alles, was es wert ist, n (n + 1) / 2 + 1 zu sein scheint - und ich war nicht klug genug, um das herauszufinden, ich habe OEIS verwendet . :) :)
Hier ist die Funktion mit den Click-Event-Handlern, die aktiv sind. hoffentlich ist es leicht zu verstehen (lass es mich wissen, wenn nicht, ich möchte auch darin besser werden):
/** 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
}
});
}
Bitte lassen Sie mich wissen, wenn Sie Ideen oder Vorschläge haben oder wenn die Lösung für mein Problem einer Lösung für ein anderes Problem hier ähnlich ist (ich habe mir viele Threads mit ähnlichen Titeln angesehen und hatte kein Glück, eine Lösung zu finden, die funktionieren könnte für mich).
quelle
var amount = parseInt(this.id.replace(/[^\d]/g,''),10);
Und wenn Sie die gleiche Eigenschaft eines Elements verwenden werden mehr als einmal Cache diese Eigenschaft, nicht halten es bis suchen. Die Suche ist teuer.Antworten:
Um sicherzustellen, dass nur einmal geklickt wird, verwenden Sie Folgendes:
quelle
.unbind()
ist veraltet und Sie sollten.off()
stattdessen die Methode verwenden. Rufen.off()
Sie einfach direkt vor Ihrem Anruf an.on()
.Dadurch werden alle Ereignishandler entfernt:
So entfernen Sie nur registrierte 'Click'-Ereignishandler:
quelle
.einer()
Eine bessere Option wäre
.one()
:Bei mehreren Klassen und jeder Klasse muss einmal geklickt werden,
quelle
onclick
Ereignisse auf das gleiche Element , sondern an verschiedenen Orten wird dies den Rest nicht beeinflussen, währendunbind()
undoff()
zerstören nur andereonclick
s danke wiederWenn Sie feststellen, dass .off () .unbind () oder .stopPropagation () Ihr spezifisches Problem immer noch nicht beheben, versuchen Sie es mit .stopImmediatePropagation (). Funktioniert hervorragend in Situationen, in denen Ihr Ereignis nur ohne und ohne Sprudeln behandelt werden soll Auswirkungen auf andere Ereignisse, die bereits behandelt werden. Etwas wie:
macht den Trick!
quelle
Wenn Sie diese Funktion bei jedem "Klick" aufrufen, wird bei jedem Aufruf ein weiteres Handlerpaar hinzugefügt .
Das Hinzufügen von Handlern mit jQuery entspricht nicht dem Festlegen des Werts des Attributs "onclick". Man kann so viele Handler hinzufügen, wie man möchte.
quelle
Ein Ereignis wird mehrmals ausgelöst, wenn es mehrmals registriert wird (auch wenn es sich um denselben Handler handelt).
zB
$("ctrl").on('click', somefunction)
wenn dieses Stück Code jedes Mal , wenn die Seite ausgeführt wird , wird teilweise aktualisiert, wird das Ereignis jedes Mal zu registriert. Selbst wenn die Strg-Taste nur einmal angeklickt wird, kann sie "irgendeine Funktion" mehrmals ausführen. Wie oft sie ausgeführt wird, hängt davon ab, wie oft sie registriert wurde.Dies gilt für alle in Javascript registrierten Ereignisse.
Lösung:
Stellen Sie sicher, dass Sie nur einmal "an" rufen.
und aus irgendeinem Grund, wenn Sie die Architektur nicht steuern können, gehen Sie folgendermaßen vor:
$("ctrl").off('click'); $("ctrl").on('click', somefunction);
quelle
Ich hatte ein Problem wegen Markup.
HTML:
jQuery
Sie bemerken, dass ich dieselbe Klasse 'myclass' zweimal in HTML habe, also ruft es click für jede Instanz von div auf.
quelle
Die bessere Option wäre off
quelle
Das ganze Zeug über .on () und .one () ist großartig, und jquery ist großartig.
Aber manchmal möchten Sie, dass es etwas offensichtlicher ist, dass der Benutzer nicht klicken darf, und in diesen Fällen können Sie Folgendes tun:
und Ihr Knopf würde aussehen wie:
quelle
Dies geschieht, weil das jeweilige Ereignis mehrmals an dasselbe Element gebunden ist.
Die Lösung, die für mich funktioniert hat, ist:
Töte alle angehängten Ereignisse mit der
.die()
Methode.Und dann hängen Sie Ihren Methoden-Listener an.
Somit,
sollte sein:
quelle
stopPropagation()
Um zu vermeiden, dass Klicks das Ereignis zu oft auslösen, müssen wir dies tun.Es verhindert, dass das Ereignis in den DOM-Baum sprudelt, und verhindert, dass übergeordnete Handler über das Ereignis benachrichtigt werden. Diese Methode akzeptiert keine Argumente.
Wir können verwenden,
event.isPropagationStopped()
um festzustellen, ob diese Methode jemals aufgerufen wurde (für dieses Ereignisobjekt).Diese Methode funktioniert auch für benutzerdefinierte Ereignisse, die mit trigger () ausgelöst werden. Beachten Sie, dass dies nicht verhindert, dass andere Handler auf demselben Element ausgeführt werden.
quelle
In meinem Fall habe ich "Delegate" verwendet, sodass keine dieser Lösungen funktioniert hat. Ich glaube, es war die Schaltfläche, die mehrmals über Ajax-Aufrufe angezeigt wurde und das Problem mit mehreren Klicks verursachte. Die Lösungen verwendeten eine Zeitüberschreitung, sodass nur der letzte Klick erkannt wird:
quelle
Docs:
http://api.jquery.com/one/
quelle
quelle
.one wird während der gesamten Lebensdauer der Seite nur einmal ausgelöst
Wenn Sie also eine Validierung durchführen möchten, ist dies nicht die richtige Lösung, da Sie nie wieder zurückkehren, wenn Sie die Seite nach der Validierung nicht verlassen. Besser zu benutzen
quelle
Wenn ich mich mit diesem Problem befasse, verwende ich immer:
Auf diese Weise binde ich mich im selben Strich und wieder.
quelle
https://jsfiddle.net/0vgchj9n/1/
Um sicherzustellen, dass das Ereignis immer nur einmal ausgelöst wird, können Sie Jquery .one () verwenden. JQuery One stellt sicher, dass Ihr Event-Handler nur einmal aufgerufen wird. Darüber hinaus können Sie Ihren Ereignishandler mit einem abonnieren, um weitere Klicks zuzulassen, wenn Sie die Verarbeitung des aktuellen Klickvorgangs abgeschlossen haben.
…
quelle
Versuchen Sie es so:
quelle
In meinem Fall wurde das Ereignis onclick mehrmals ausgelöst, da ich einen generischen Ereignishandler vergleichsweise als erstellt hatte
gewechselt zu
Außerdem müssen separate Handler für statische und dynamische Klicks für statische Tabulatoren erstellt werden
quelle
In meinem Fall hatte ich dieselbe
*.js
Datei zweimal in einem<script>
Tag auf die Seite geladen , sodass beide Dateien Ereignishandler an das Element anhängten. Ich habe die doppelte Deklaration entfernt und das Problem behoben.quelle
Eine andere Lösung, die ich gefunden habe, war folgende: Wenn Sie mehrere Klassen haben und sich mit Optionsfeldern befassen, während Sie auf das Etikett klicken.
quelle
Ich hatte dieses Problem mit einem dynamisch generierten Link:
$(document).on('click', '#mylink', function({...do stuff...});
Ich habe festgestellt, dass das Problem durch Ersetzen
document
durch'body'
behoben wurde:$('body').on('click', '#mylink', function({...do stuff...});
quelle
Unbind () funktioniert, aber das könnte in Zukunft andere Probleme verursachen. Der Handler wird mehrmals ausgelöst, wenn er sich in einem anderen Handler befindet. Lassen Sie Ihren Handler also draußen. Wenn Sie die Werte des verschachtelten Handlers verwenden möchten, weisen Sie sie einer globalen Variablen zu, auf die Ihr Handler zugreifen kann.
quelle
Falls dies gut funktioniert
quelle
Der folgende Code hat in meiner Chat-Anwendung funktioniert, um mehrere Mausklick-auslösende Ereignisse mehr als einmal zu verarbeiten.
if (!e.originalEvent.detail || e.originalEvent.detail == 1) { // Your code logic }
quelle