jQuery 多次在父元素上触发点击事件

jQuery click event fires on parent element multiple times

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");
      }
    });
  },

我正在编写一个 Tic-Tac-Toe 游戏,运行 解决了这个问题 - 当多个会话 "played" 点击事件不断复合时。 我通过每次在附加新点击事件之前清除之前的点击事件来解决这个问题。

$(".game-screen").off().on("click", ".tic", function () { //do stuff }

顺便说一下,event.stopPropagation() 和 event.stopImmediatePropagation() 没有 工作。

无论如何,虽然我设法解决了问题并理解了为什么点击事件复合,但我似乎无法理解的是为什么这些复合点击事件一直调用 parent 函数 gameLogic: function()。连续尝试 "playing" 几个会话 -

console.log("GAME LOGIC"); alert("Your Turn!"); 每次会话都会被调用成倍增加。 jQuery 是不是用父函数来跟踪点击事件之类的?谁能解释幕后发生的事情?为什么事件处理程序一直引用父函数?

将您的函数实现从 gameLogic 函数中移出,如下所示;

function gameScreenClick(){
 // your click event handler code.....
} 

然后

$(".game-screen").on("click", ".tic", gameScreenClick);

我跟踪了调用堆栈,并查看了 jQuery dispatch: function()。实际上,事实证明,问题不在于 jQuery 内部引用其点击功能和处理程序的方式。

罪魁祸首在第 46 行。getUserInput() 附加了一个事件处理程序,该事件处理程序又附加了 chooseFaction() 事件处理程序。在下一个会话中,getUserInput() 又被附加了一次,chooseFaction() 被附加了 2 次(比之前增加了 1 次)——因此 chooseFaction() 触发了 3 次调用 generateBoard(),并且反过来,调用 gameLogic() 等。因此,对 gameLogic() 的调用随着每次迭代呈指数增长。

$(.game-screen).off() 移动到 restartGame() 函数,以在开始新会话之前删除所有点击事件,作为更简洁的解决方案。

解决方案:https://jsfiddle.net/50Lw423g/4/