2017-07-26 94 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