无法删除事件监听器

时间:2017-07-26 22:15:56

标签: javascript canvas addeventlistener

我正在使用socket.io进行一个简单的Pong游戏,它将state.player设置为0以使用户成为屏幕左侧的paddle,并将state.player设置为1以显示屏幕的右侧。

最终玩家将切换位置,因此需要移除并重新添加让鼠标控制屏幕右侧/左侧拨片的事件监听器,以便他们在屏幕的正确一侧控制正确的拨片。

我在某处读到你必须将函数存储在变量中然后在变量上调用removeEventListener,但这似乎并没有起作用。我在添加一个事件监听器之前将其删除,以便鼠标只能在屏幕的正确一侧控制正确的拨片。但当它们切换侧面时,鼠标控制两侧。

const choosePlayerSide = (player) =>{

    function getLeftMouse(e){
            let mousePos = calcMousePos(e);         
            lpaddle.y = mousePos.y - PADDLE_HEIGHT / 2;
            socket.emit('mousePos', mousePos);              
    }

    function getRightMouse(e){
            let mousePos = calcMousePos(e);         
            rpaddle.y = mousePos.y - PADDLE_HEIGHT / 2;
            socket.emit('mousePos', mousePos);              
    }

    const gr = getRightMouse;
    const gl = getLeftMouse;

    if(player === 0){           
        console.log('choosing player 0')
        this.setPlayer(0);
        // Reset Event Listeners
        canvas.removeEventListener('mousemove', gr);
        canvas.removeEventListener('mousemove', gl);

        canvas.addEventListener('mousemove', gl);

        this.setInPlay();
    }
    else if(player === 1){
        console.log('choosing player 1')
        this.setPlayer(1);

        canvas.removeEventListener('mousemove', gr);
        canvas.removeEventListener('mousemove', gl);

        canvas.addEventListener('mousemove', gr);


        this.setInPlay();
        socket.emit('newplayer');

    }       
}

2 个答案:

答案 0 :(得分:1)

每次调用外部函数并执行时,嵌套在另一个函数体中的函数声明会创建新的函数对象。

每次调用getLeftMouse时都会创建getRightMousechoosePlayerSide的新实例,并且无法用于删除之前调用中添加的事件侦听器。< / p>

相关错误是在调用addEventListener时使用函数表达式。每次添加事件监听器时都会创建一个新函数,通过在稍后调用removeEventListener的语句中重复相同的函数表达式来删除它(评估每个函数表达式创建一个新的不同的函数对象) 。这是将处理函数存储在变量&#34;中的建议的来源。解决涉及函数表达式的这个版本的问题。

请注意,const在编译时不会初始化变量并将其存储以便在多个调用中使用。它保护变量值在初始化后不被修改,但每次在函数代码中执行语句时都执行初始化。

要解决此问题,请在比getLeftMouse更全局的级别声明getRightMousechoosePlayerSide。根据游戏应用程序的组合方式,这可能在用于创建游戏的IEFE中或实际上在全局名称空间内(不推荐)。执行此操作后,您可以在添加/删除事件侦听器调用中使用其名称,而无需在局部变量glgr中复制它们的值。

答案 1 :(得分:0)

试试这个:

var _this = this;
addEventListener('click', this.clickhandler);
removeEventListener('click', this.clickhandler);
clickhander = (function () { _this.   ; }); //use _this inside