简体   繁体   English

在jQuery中禁用事件处理程序

[英]Disabling event handler in jQuery

I'm creating a simple tic-tac-toe game and I have an event handler that triggers a lot of the functions in the code. 我正在创建一个简单的井字游戏,并且有一个事件处理程序可以触发代码中的许多功能。 The thing is, when the game is over, I want to disable that event handler so that the game can end and the user cannot interact with it. 问题是,当游戏结束时,我想禁用该事件处理程序,以便游戏可以结束并且用户无法与其进行交互。 I've looked into it and unbind/bind, on/off/ prop/attr nulling don't work. 我已经研究了它,并且取消绑定/绑定,打开/关闭/ prop / attr调零无效。 Is there any other way to disable this event handler when a condition is met? 满足条件时,还有其他方法可以禁用此事件处理程序吗? I want to disable the .one('click') handler not the beginning parent handler. 我想禁用.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);
    });
});

Try defining it as a function instead: 尝试将其定义为函数:

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

And then attach it: 然后附加:

$('td').one('click', handler);

Whenever you want to remove it you can just go: 每当您要删除它时,您都可以去:

$('td').off('click', handler);

EDIT: you'll need to define the handler variable before you take it off, but that should be reasonable. 编辑:您需要先定义处理程序变量,然后再将其删除,但这应该是合理的。 Just define it at the top and set it before you call one and it should be available to any other part of the code. 而就在上面定义它,并将其设置在打电话前one ,它应该是提供给代码的任何其他部分。

EDIT: Took a look at your fiddle. 编辑:看了看你的小提琴。 See http://jsfiddle.net/c4496/1/ for a working solution. 有关有效的解决方案,请参见http://jsfiddle.net/c4496/1/ Like I said earlier, $.off always works: your usage was wrong. 就像我之前说的, $.off始终有效:您的用法是错误的。 To do what you wanted you have to invoke the $.off call at the moment you detect that you want to end the game, not write the code at the bottom and expect it to get magically invoked for you anytime you change the variable value. 要执行所需的操作,必须在检测到要结束游戏时立即调用$.off调用,而不是在底部编写代码,并希望在您更改变量值时可以为您神奇地调用它。 If you want that sort of behavior go look at Knockout or AngularJS. 如果您想要这种行为,请查看Knockout或AngularJS。

Have you tried disabling the element on which the click event occurs ? 您是否尝试过禁用发生点击事件的元素? For example, if you want to disable click on your td element, you can use : 例如,如果要禁用单击td元素,则可以使用:

$('td').prop("disabled",true);

and when you want to re-enable it just use : 而当您想重新启用它时,只需使用:

$('td').prop("disabled",false);

Nulling the prop or attr methods won't help. 取消prop或attr方法将无济于事。 Use the above way. 使用上面的方法。 Hope it helps ! 希望能帮助到你 !

Use .off() and event name spacing 使用.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);
});

Demo: Fiddle 演示: 小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM