Reputation: 109
https://jsfiddle.net/50Lw423g/2/
gameLogic: function() {
console.log("GAME LOGIC");
alert("Your Turn!");
var that = this;
$(".game-screen").on("click", ".tic", function() {
console.log("EVENT ATTACHED");
var movesDisplay = $(this).text(),
playerOne = that.playerOneMoves,
moveID = +(this.id);
if (movesDisplay !== "O" && movesDisplay !== "X") {
that.playerOneMoves.push(moveID);
if (playerOne.length > 2) {
if (that.checkIfWinCondition(playerOne, that.winConditions)) {
alert("GAME OVER!");
that.inGame = false;
ticTacToe.restartGame();
}
}
$(this).text(that.playerFaction === "X" ? "X" : "O");
}
});
},
I'm writing a Tic-Tac-Toe game and ran into this problem - when multiple sessions are "played" click events keep compounding. Which I solved by clearing the previous click events every time before a new one is attached.
$(".game-screen").off().on("click", ".tic", function () { //do stuff }
By the way event.stopPropagation() and event.stopImmediatePropagation() did NOT work.
Anyway, while I managed to fix the problem and understand why the click events where compounding, what I can't seem to wrap my head around is why those compounded click events kept calling the parent function gameLogic: function()
. Try "playing" several sessions in a row -
console.log("GAME LOGIC");
alert("Your Turn!");
get called exponentially more with every session. Does jQuery use the parent function to track the click events or something? Can anyone explain what's happening under the hood? Why do the event handlers keep referring to the parent function?
Upvotes: 0
Views: 230
Reputation: 109
I traced the call stack, and looked at the jQuery dispatch: function()
. Actually, as it turns out, the problem wasn't with the way jQuery internally refers to it's click functions and handlers.
The culprit was on line 46. The getUserInput()
attaches an event handler which in turn attaches the chooseFaction()
event handler. On the next session, getUserInput()
gets attached one more time and chooseFaction()
is attached 2 times (+1 time from before) - so chooseFaction()
fires 3 times calling generateBoard()
, and in turn, calling gameLogic()
etc. Thus calls to gameLogic()
exponentially increasing with every iteration.
Moved $(.game-screen).off()
to the restartGame()
function, to remove all click events before starting a new session, as a cleaner solution.
Solution: https://jsfiddle.net/50Lw423g/4/
Upvotes: 0
Reputation: 1890
Move your function implementation out from the gameLogic function like bellow;
function gameScreenClick(){
// your click event handler code.....
}
then
$(".game-screen").on("click", ".tic", gameScreenClick);
Upvotes: 1