Javascript 带有requestAnimationFrame的addEventListener

Javascript 带有requestAnimationFrame的addEventListener,javascript,addeventlistener,requestanimationframe,game-loop,Javascript,Addeventlistener,Requestanimationframe,Game Loop,我正在使用window.requestAnimationFrame创建一个游戏循环 一切都很好,但当我尝试添加一个事件侦听器时,它会快速启动数百次 我尝试过使用闭包,但似乎不起作用 game.update = function(){ //code that runs every frame window.addEventListener('keydown', function(){ console.log("message"); },false); } 我想对ke

我正在使用
window.requestAnimationFrame
创建一个游戏循环

一切都很好,但当我尝试添加一个事件侦听器时,它会快速启动数百次

我尝试过使用闭包,但似乎不起作用

game.update = function(){
   //code that runs every frame
   window.addEventListener('keydown', function(){
      console.log("message");
   },false);
}

我想对keydown事件调用函数一次,而不是多次。

只有在添加新的侦听器时才会添加事件侦听器。多次添加同一个侦听器没有效果

将侦听器函数移出分配给
游戏的函数。更新
,以便在每次调用
addEventListener()
时不会创建侦听器的新副本:

var updateListener=function(){
console.log('message');
};
game.update=函数(){
//每帧运行的代码
addEventListener('keydown',updateListener,false);
};

可能有点晚了,但这对我来说没什么意义。不应在RAF内部添加侦听器。如果您将其放在外部,并将处理程序的结果分配给一个变量,然后让RAF获得结果并清除该变量,您将获得更快、更稳定/更可预测的性能。这对于类似的任务来说非常明显,例如在移动设备上使用面向设备的侦听器进行控制器输入。事件不需要循环。设置一次,每次按下一把钥匙,它就会触发一次。RAF只能用于更新图形。任何其他逻辑都应该在它之外。例如,动作和游戏机制应该在一个设定区间内,将结果指向RAF可访问的外部变量和对象。RAF只应拾取新的位置值并设置变换。然后,它将运行得更平稳,“时间”不会加速或减慢,并且在不同的设备上保持一致,而不管帧速率如何。

“我希望在keydown事件中调用函数一次,而不是多次。”然后,在调用函数后,您必须解除该函数的绑定。为什么要在循环中绑定事件处理程序?为什么不出去?是否希望处理程序每帧运行一次?请更好地解释您正试图解决的问题。您需要添加事件侦听器一次,而不是在更新循环中。更新循环只应在创建对象时向其创建的对象添加事件侦听器。只是不要在每个frameOk运行的函数中运行该代码。由于某种原因,它只是想把它扔进循环中。