Próbuję napisać grę w pokera wideo w Javascripcie jako sposób na zapoznanie się z jej podstawami i napotkałem problem polegający na tym, że programy obsługi zdarzeń kliknięcia jQuery uruchamiają się wielokrotnie.
Są one przymocowane do przycisków służących do obstawiania i działa dobrze przy obstawianiu pierwszego rozdania podczas gry (strzelanie tylko raz); ale w zakładach na drugie rozdanie uruchamia zdarzenie kliknięcia dwa razy za każdym razem, gdy zostanie naciśnięty przycisk zakładu lub postawienia zakładu (więc dwukrotność prawidłowej kwoty za każde naciśnięcie). Ogólnie rzecz biorąc, następuje to według tego, ile razy zdarzenie kliknięcia jest uruchamiane po jednokrotnym naciśnięciu przycisku zakładu - gdzie i-ty termin sekwencji dotyczy zakładów i-tego rozdania od początku gry: 1, 2, 4 , 7, 11, 16, 22, 29, 37, 46, który wydaje się być n (n + 1) / 2 + 1 dla tego, co jest warte - i nie byłem wystarczająco inteligentny, aby to zrozumieć, użyłem OEIS . :)
Oto funkcja z działającymi funkcjami obsługi zdarzeń kliknięcia; miejmy nadzieję, że łatwo to zrozumieć (daj mi znać, jeśli nie, chcę też być lepszy):
/** 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
}
});
}
Daj mi znać, jeśli masz jakieś pomysły lub sugestie lub jeśli rozwiązanie mojego problemu jest podobne do rozwiązania innego problemu tutaj (przejrzałem wiele podobnie utytułowanych wątków i nie miałem szczęścia znaleźć rozwiązania, które mogłoby zadziałać dla mnie).
źródło
var amount = parseInt(this.id.replace(/[^\d]/g,''),10);
A jeśli zamierzasz użyć tej samej właściwości elementu więcej niż raz, buforuj tę właściwość, nie szukaj dalej. Wyszukiwanie jest drogie.Odpowiedzi:
Aby mieć pewność, że działania wykonywane tylko za jednym kliknięciem, użyj tego:
źródło
.unbind()
jest przestarzałe i.off()
zamiast tego należy użyć tej metody. Po prostu zadzwoń,.off()
zanim zadzwonisz.on()
.Spowoduje to usunięcie wszystkich procedur obsługi zdarzeń:
Aby usunąć tylko zarejestrowane programy obsługi zdarzeń „kliknięcia”:
źródło
.jeden()
Lepszą opcją byłoby
.one()
:W przypadku wielu klas i każdej klasy należy kliknąć raz,
źródło
onclick
zdarzeń do tego samego elementu, ale w różnych miejscach to nie wpłynie na odpoczynek, podczasunbind()
ioff()
po prostu niszczą inneonclick
s dziękuję jeszcze razJeśli stwierdzisz, że .off () .unbind () lub .stopPropagation () nadal nie rozwiązuje konkretnego problemu, spróbuj użyć .stopImmediatePropagation () działa świetnie w sytuacjach, gdy chcesz, aby Twoje zdarzenie było obsługiwane bez propagacji i bez wpływające na inne obsługiwane już zdarzenia. Coś jak:
Zrób sztuczkę!
źródło
Jeśli wywołujesz tę funkcję przy każdym „kliknięciu”, to dodaje kolejną parę procedur obsługi dla każdego połączenia.
Dodanie modułów obsługi za pomocą jQuery po prostu nie przypomina ustawiania wartości atrybutu „onclick”. Można dodać dowolną liczbę programów obsługi.
źródło
wydarzenie zostanie uruchomione wiele razy, jeśli zostanie zarejestrowane wielokrotnie (nawet jeśli dotyczy tego samego modułu obsługi).
np.
$("ctrl").on('click', somefunction)
jeśli ten fragment kodu jest wykonywany za każdym razem, gdy strona jest częściowo odświeżana, zdarzenie jest również rejestrowane za każdym razem. Dlatego nawet jeśli klikniesz ctrl tylko raz, może on wykonać wielokrotnie „jakąś funkcję” - ile razy wykona, będzie zależeć od tego, ile razy został zarejestrowany.dotyczy to każdego zdarzenia zarejestrowanego w javascript.
rozwiązanie:
pamiętaj, aby zadzwonić tylko raz.
i z jakiegoś powodu, jeśli nie możesz kontrolować architektury, zrób to:
$("ctrl").off('click'); $("ctrl").on('click', somefunction);
źródło
Miałem problem z powodu znaczników.
HTML:
jQuery
Zauważysz, że mam dwukrotnie tę samą klasę „myclass” w html, więc wywołuje kliknięcie dla każdej instancji div.
źródło
Lepszą opcją byłoby wyłączenie
źródło
Wszystkie rzeczy związane z .on () i .one () są świetne, a jquery jest świetne.
Ale czasami chcesz, aby było trochę bardziej oczywiste, że użytkownik nie może kliknąć, aw takich przypadkach możesz zrobić coś takiego:
a twój przycisk wyglądałby tak:
źródło
Dzieje się tak, ponieważ dane zdarzenie jest wielokrotnie powiązane z tym samym elementem.
Rozwiązaniem, które działało dla mnie jest:
Zabij wszystkie zdarzenia dołączone za pomocą
.die()
metody.A następnie dołącz swój detektor metod.
A zatem,
Powinien być:
źródło
Musimy
stopPropagation()
, aby zbyt wiele razy unikać zdarzenia uruchamiającego kliknięcia.Zapobiega to propagacji zdarzenia w drzewie DOM, zapobiegając powiadamianiu o zdarzeniu przez wszystkie programy nadrzędne. Ta metoda nie przyjmuje żadnych argumentów.
Możemy użyć
event.isPropagationStopped()
do ustalenia, czy ta metoda została kiedykolwiek wywołana (dla tego obiektu zdarzenia).Ta metoda działa również w przypadku niestandardowych zdarzeń wyzwalanych za pomocą trigger (). Należy pamiętać, że nie zapobiegnie to uruchomieniu innych procedur obsługi tego samego elementu.
źródło
W moim przypadku korzystałem z funkcji „deleguj”, więc żadne z tych rozwiązań nie działało. Wydaje mi się, że to przycisk pojawiający się wiele razy za pośrednictwem wywołań ajax powodował problem z wieloma kliknięciami. Rozwiązania wykorzystywały limit czasu, więc rozpoznawane jest tylko ostatnie kliknięcie:
źródło
Dokumenty:
http://api.jquery.com/one/
źródło
źródło
.one strzela tylko raz przez cały czas istnienia strony
Jeśli więc chcesz przeprowadzić walidację, nie jest to właściwe rozwiązanie, ponieważ jeśli nie opuścisz strony po walidacji, nigdy nie wrócisz. Lepszy w użyciu
źródło
Kiedy rozwiązuję ten problem, zawsze używam:
W ten sposób rozpinam i ponownie wiążę jednym pociągnięciem.
źródło
https://jsfiddle.net/0vgchj9n/1/
Aby mieć pewność, że zdarzenie zawsze uruchamia się tylko raz, możesz użyć Jquery .one (). JQuery one zapewnia, że moduł obsługi zdarzeń wywoływany jest tylko raz. Ponadto możesz zasubskrybować moduł obsługi zdarzeń za pomocą jednego, aby umożliwić dalsze kliknięcia po zakończeniu przetwarzania bieżącej operacji kliknięcia.
…
źródło
Spróbuj w ten sposób:
źródło
W moim przypadku zdarzenie onclick było uruchamiane wiele razy, ponieważ stworzyłem ogólną procedurę obsługi zdarzeń podobnie jak
zmienić na
a także muszą tworzyć osobne procedury obsługi dla kliknięć statycznych i dynamicznych, dla statycznych kliknięć kart
źródło
W moim przypadku
*.js
dwukrotnie załadowałem ten sam plik na stronę w<script>
tagu, więc oba pliki dołączały procedury obsługi zdarzeń do elementu. Usunąłem duplikat deklaracji i to rozwiązało problem.źródło
Innym rozwiązaniem, które znalazłem, było to, że jeśli masz wiele klas i masz do czynienia z przyciskami opcji podczas klikania etykiety.
źródło
Miałem ten problem z linkiem generowanym dynamicznie:
$(document).on('click', '#mylink', function({...do stuff...});
Znalazłem wymianie
document
z'body'
Naprawiono problem dla mnie:$('body').on('click', '#mylink', function({...do stuff...});
źródło
Unbind () działa, ale może to powodować inne problemy w przyszłości. Program obsługi uruchamia się wiele razy, gdy znajduje się w innym module obsługi, więc trzymaj swój moduł obsługi na zewnątrz, a jeśli chcesz wartości modułu obsługi, który się zagnieździł, przypisz je do zmiennej globalnej, która będzie dostępna dla twojego modułu obsługi.
źródło
Jeśli to działa dobrze
źródło
Poniższy kod działał dla mnie w mojej aplikacji czatu do obsługi wielu zdarzeń wyzwalających kliknięcie myszą więcej niż raz.
if (!e.originalEvent.detail || e.originalEvent.detail == 1) { // Your code logic }
źródło