我正在创建一个简单的tic-tac-toe游戏,我有一个事件处理程序,可以触发代码中的许多功能。问题是,当游戏结束时,我想禁用该事件处理程序,以便游戏可以结束,用户无法与之交互。我调查了它并取消绑定/绑定,on / off / prop / attr nulling不起作用。有没有其他方法可以在满足条件时禁用此事件处理程序?我想禁用.one('click')处理程序而不是开头的父处理程序。
//Creates the variables needed to be manipulated later
$(document).ready(function () {
var X = 'X';
var O = 'O';
var currentPlayer;
var turnCount = 0;
var xMoves = [];
var oMoves = [];
var cellTracker;
var winAlert;
var winConditions = [
['c1', 'c2', 'c3'],
['c4', 'c5', 'c6'],
['c7', 'c8', 'c9'],
['c1', 'c4', 'c7'],
['c2', 'c5', 'c8'],
['c3', 'c6', 'c9'],
['c1', 'c5', 'c9'],
['c3', 'c5', 'c7']
];
/*Set's the current player to X if turnCount is odd
And to O if turnCount is even*/
var setCurrentPlayer = function () {
if (turnCount % 2 === 0) {
currentPlayer = O;
} else {
currentPlayer = X;
}
};
//Pushes cellTracker's value to the curent player's move variable
var storeMoves = function () {
if (currentPlayer === X) {
xMoves.push(cellTracker);
} else if (currentPlayer === O) {
oMoves.push(cellTracker);
}
};
//Compares players moves with the winConditions to determine a winner
var determineWin = function (pMoves) {
for (var i = 0; i < winConditions.length; i++) {
if (winConditions[i].length > pMoves.length) {
continue;
}
for (var j = 0; j < winConditions[i].length; j++) {
winAlert = false;
for (var k = 0; k < pMoves.length; k++) {
if (pMoves[k] === winConditions[i][j]) {
winAlert = true;
break;
}
}
if (!winAlert) break;
}
if (winAlert) {
alert(currentPlayer + " wins!");
break;
}
}
};
/*Place's an X or an O when a cell is clicked depending
on the current player, and updates the turnCount*/
$('td').one('click', function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
determineWin(currentPlayer == 'X' ? xMoves : oMoves);
if (turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
});
答案 0 :(得分:1)
尝试将其定义为函数:
var handler = function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
determineWin(currentPlayer == 'X' ? xMoves : oMoves);
if (turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
然后附上它:
$('td').one('click', handler);
每当你想删除它时,你都可以去:
$('td').off('click', handler);
编辑:你需要在取消之前定义处理程序变量,但这应该是合理的。只需在顶部定义并在调用one
之前设置它,它应该可用于代码的任何其他部分。
$.off
总是有效:你的使用是错误的。要做你想做的事情,你必须在你发现想要结束游戏的那一刻调用$.off
调用,不要在底部编写代码并期望在你改变变量的时候为你神奇地调用它值。如果您想要这种行为,请查看Knockout或AngularJS。
答案 1 :(得分:0)
您是否尝试过禁用发生点击事件的元素?例如,如果要禁用单击td
元素,可以使用:
$('td').prop("disabled",true);
如果您想重新启用它,只需使用:
$('td').prop("disabled",false);
取消prop或attr方法无济于事。使用上面的方法。希望它有所帮助!
答案 2 :(得分:0)
使用.off()和事件名称间距
$('td').one('click.mygame', function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
determineWin(currentPlayer == 'X' ? xMoves : oMoves);
if (turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
if(condition){ //like ( winAlert === true || turnCount === 9)
$('td').off('click.mygame')
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
演示:Fiddle