Javascript addeventListner仅在循环中所有迭代结束时工作

Javascript addeventListner仅在循环中所有迭代结束时工作,javascript,event-listener,Javascript,Event Listener,我想做一个类似吉他英雄的游戏。我希望用户按键盘上的右键。当前,所有必需的键都会首先高亮显示,然后只有用户才能按这些键,因为事件侦听器只有在循环的所有迭代之后才能工作。这些键同时出现 这不是我想要的。我希望按键以固定的间隔出现,用户应在时间限制内按右键 那么,如何让evetListner在循环的每次迭代中运行呢 var flag = 0; //to generate random key function getRandmFromSet(set) { var rndm

我想做一个类似吉他英雄的游戏。我希望用户按键盘上的右键。当前,所有必需的键都会首先高亮显示,然后只有用户才能按这些键,因为事件侦听器只有在循环的所有迭代之后才能工作。这些键同时出现

这不是我想要的。我希望按键以固定的间隔出现,用户应在时间限制内按右键

那么,如何让evetListner在循环的每次迭代中运行呢

var flag = 0;

//to generate  random key
    function getRandmFromSet(set) {
        var rndm = Math.floor(Math.random() * set.length);
        return set[rndm];
    }
    function actualGame(){
    var key_chosen = getRandmFromSet([65, 83, 68, 70, 71, 72, 74, 75, 76]);

    const key = document.querySelector(`.key[data-key="${key_chosen}"]`);
    console.log(key);
    key.classList.add("playingBeforePress");//animation

    window.addEventListener('keydown', function (e) {
        const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
        const key_pressed = document.querySelector(`.key[data-key="${e.keyCode}"]`);
        const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);

        if (e.keyCode == key_chosen) { //to check if the pey pressed is the right key
            console.log("correct key pressed");
            audio.currentTime = 0; 
            audio.play();
            key.classList.add("playingAfterPress");//animation
            setTimeout(function () {
                key_pressed.classList.remove("playingAfterPress");
            }, 100)

        }
        else {
            console.log("wrong key pressed");
            flag = 1
        }

    });
    };

    for(let i=0;i<5;++i){  //to generate 5 keys
        actualGame();
        }
var标志=0;
//生成随机密钥
函数getRandmFromSet(集合){
var rndm=Math.floor(Math.random()*set.length);
返回集[rndm];
}
函数ActualName(){
var key_selected=getRandmFromSet([65,83,68,70,71,72,74,75,76]);
const key=document.querySelector(`.key[data key=“${key\u selected}”]`);
控制台日志(键);
key.classList.add(“playingBeforePress”);//动画
window.addEventListener('keydown',函数(e){
const audio=document.querySelector(`audio[data key=“${e.keyCode}]”);
const key_pressed=document.querySelector(`.key[data key=“${e.keyCode}]”);
const key=document.querySelector(`.key[data key=“${e.keyCode}]”);
如果(e.keyCode==key_selected){//检查按下的pey键是否正确
console.log(“按下正确的键”);
audio.currentTime=0;
音频播放();
key.classList.add(“playingAfterPress”);//动画
setTimeout(函数(){
按键按下。类别列表。移除(“按下后播放”);
}, 100)
}
否则{
console.log(“按错键”);
标志=1
}
});
};

对于(让i=0;i你应该从另一个角度来研究这个问题,本质上你只需要一个事件监听器,这个监听器添加到你的
主体
,它将监听关键点。然后你需要一个列表来检查有效性,然后你需要使用动画来显示这个反馈。我重构了你的代码,使之能够一致且简单地工作:

函数监听(事件){
让key=document.querySelector(`.key[data key=“${event.keyCode}]”);
让audio=document.querySelector(`audio[data key=“${event.keyCode}]”);
if(key&&keys.indexOf(event.keyCode)>=0){
console.log('按下右键');
//禁用,因为它不会在堆栈溢出(CORS)上工作
//audio.currentTime=0;
//音频播放();
函数结束(){
key.classList.remove('right');
键。removeEventListener('animationend',结束);
}
键。addEventListener('animationend',结束);
key.classList.add('right');
}否则{
console.log('按错键');
flag=1;
如果(关键){
函数结束(){
key.classList.remove('error');
键。removeEventListener('animationend',结束);
}
键。addEventListener('animationend',结束);
key.classList.add('error');
}
}
}
//生成所需DOM的快速方法
函数生成域(键){
document.getElementById('keys').innerHTML=keys.reduce((html,key)=>{
html+=`${key}`;
返回html;
}, '');
}
//箭头键
var键=[37,38,39,40];
//箭头键+空格键+回车键
generateDOM([].concat(键[32,13]);
//为所有按键事件添加一个侦听器
document.addEventListener('keydown',listen);
@右关键帧{
20%{背景:绿色;}
}
@关键帧错误{
20%{背景:红色;}
}
.钥匙{
宽度:80px;
高度:80px;
字体大小:20px;
字体系列:monospace;
框大小:边框框;
填充:30px0;
文本对齐:居中;
背景:浅灰色;
显示:内联块;
}
.错了{
动画:错误的2秒;
}
.对{
动画:右2s;
}

您添加的五个相同的事件侦听器已经在运行。您是否需要在
按键后每100ms调用一次
setTimeout
回调?然后您需要重新考虑您的逻辑。添加一个事件侦听器,而不是其中的五个。只有一个事件侦听器,我想随机生成一个多次按键,因此我使用了循环。
setTimeout
是在用户按下正确的键时更改动画。所有5个按键侦听器都在运行,但问题是只有在选择了所有5个按键后,您才能按相应的键。我希望这样,一旦一个按键高亮显示,您必须按该键。您可以不应该使用五个事件监听器,它们都在窗口上,每按一次键都会触发一个事件监听器。只有一个事件监听器,你就可以每回合检查一次你的键。你需要从实际游戏中删除添加事件监听器的操作,因此只要按下一个键,事件监听器就会触发一次。