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

时间:2017-03-30 03:17:46

标签: javascript jquery onclick eventhandler

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游戏并遇到这个问题 - 当多个会话被播放时#34;点击事件保持复合。 我在每次附加新点击事件之前清除之前的点击事件就解决了这个问题。

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

顺便说一下,event.stopPropagation()和event.stopImmediatePropagation()做了 NOT 工作。

无论如何,当我设法解决问题并理解为什么复杂的点击事件,我似乎无法解决的问题是为什么那些复合点击事件不断调用父函数 gameLogic: function()。尝试"玩"连续几次会议 -

console.log("GAME LOGIC"); alert("Your Turn!"); 每次会话都会以指数方式调用。 jQuery是否使用父函数来跟踪点击事件或其他内容?任何人都可以解释引擎盖下发生的事情吗?为什么事件处理程序一直引用父函数?

2 个答案:

答案 0 :(得分:1)

将你的功能实现从游戏逻辑功能中移出,如下所示;

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

然后

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

答案 1 :(得分:0)

我跟踪了调用堆栈,并查看了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/