2017-07-26 41 views
0

我正在用socket.io处理一个简单的Pong游戏,它将state.player设置为0,使用户在屏幕左侧显示桨,并且将state.player设置为1屏幕一侧。Cant Remove Event Listener

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

我在某处读取必须将该函数存储在变量中,然后调用变量上的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'); 

    }  
} 

回答

1

函数声明创建的每个外部函数被调用,执行时间新的函数对象。

因此每次调用choosePlayerSide时都会创建getLeftMousegetRightMouse的新实例,并且不能用于删除先前调用中添加的事件侦听器。

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

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

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

+0

太棒了。谢谢你的解释。 – DGwang

0

试试这个:嵌套在另一个函数体内

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