addeventListner仅在循环的所有迭代结束时起作用

时间:2018-07-14 09:05:00

标签: javascript event-listener

我正在尝试制作类似于吉他英雄的游戏。我希望用户按键盘上的右键。当前,所有必需的键会先突出显示,然后只有用户才能按下这些键,因为事件侦听器仅在循环的所有迭代之后才起作用。键一次全部显示。

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

那么如何让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();
        }

1 个答案:

答案 0 :(得分:0)

您应该从另一个角度来进行处理,从本质上讲,您只需要一个事件侦听器,即一个要添加到您的body中的侦听器。然后,您需要一个列表来检查其有效性,然后您要使用动画显示此反馈。我重构了您的代码,使其始终如一地工作:

function listen( event ){
	
  let key = document.querySelector(`.key[data-key="${event.keyCode}"]`);
  let audio = document.querySelector( `audio[data-key="${event.keyCode}"]` );
	
  if( key && keys.indexOf( event.keyCode ) >= 0 ){
		
    console.log( 'right key pressed' );
		
    // Disabled since it wont work on Stack Overflow (CORS)
    // audio.currentTime = 0; 
    // audio.play();
		
    function ended(){
			
      key.classList.remove( 'right' );
      key.removeEventListener( 'animationend', ended );
			
    }
		
    key.addEventListener( 'animationend', ended );
    key.classList.add( 'right' );
		
  } else {
	
    console.log( 'wrong key pressed' );
		
    flag = 1;
		
    if( key ){
    
      function ended(){
			
        key.classList.remove( 'wrong' );
        key.removeEventListener( 'animationend', ended );
			
      }
		
      key.addEventListener( 'animationend', ended );
      key.classList.add( 'wrong' );
		
    }
    
  }
	
}


// A quick way to genersate the DOM required
function generateDOM( keys ){
  
  document.getElementById( 'keys' ).innerHTML = keys.reduce((html, key) => {
  
    html += `<div class="key" data-key="${key}">${key}</div><audio data-key="${key}"></audio>`;
    
    return html;
  
  }, '');
  
}

// Arrow Keys
var keys = [ 37, 38, 39, 40 ];

// Arrow Keys + Space + Enter
generateDOM( [].concat( keys, [ 32, 13 ] ) );

// Add a single listener for all keypress events
document.addEventListener( 'keydown', listen );
@keyframes right {
  20% { background: green; }
}
@keyframes wrong {
  20% { background: red; }
}

.key {
  
  width: 80px;
  height: 80px;
  font-size: 20px;
  font-family: monospace;
  box-sizing: border-box;
  padding: 30px 0;
  text-align: center;
  background: lightgray;
  display: inline-block;
  
}

.wrong {

  animation: wrong 2s;
  
}
.right {

  animation: right 2s;
  
}
<div id="keys"></div>

然后您的随机发生器可以这样工作:

function listen( event ){
	
  let key = document.querySelector(`.key[data-key="${event.keyCode}"]`);
  let audio = document.querySelector( `audio[data-key="${event.keyCode}"]` );
	
  if( key && keys.indexOf( event.keyCode ) >= 0 ){
		
    console.log( 'right key pressed' );
		
    // Disabled since it wont work on Stack Overflow (CORS)
    // audio.currentTime = 0; 
    // audio.play();
		
    function ended(){
			
      key.classList.remove( 'right' );
      key.removeEventListener( 'animationend', ended );
      
      newkey();
			
    }
		
    key.addEventListener( 'animationend', ended );
    key.classList.add( 'right' );
		
  } else {
	
    console.log( 'wrong key pressed' );
		
    flag = 1;
		
    if( key ){
    
      function ended(){
			
        key.classList.remove( 'wrong' );
        key.removeEventListener( 'animationend', ended );
        
        newkey();
			
      }
		
      key.addEventListener( 'animationend', ended );
      key.classList.add( 'wrong' );
      
    }
    
  }
	
}


// A quick way to genersate the DOM required
function generateDOM( keys, selected ){
  
  document.getElementById( 'keys' ).innerHTML = keys.reduce((html, key) => {
  
    html += `<div class="key${selected === key ? ' selected' : ''}" data-key="${key}">${key}</div><audio data-key="${key}"></audio>`;
    
    return html;
  
  }, '');
  
}

var keys = [];

function newkey(){
  
  var all = [ 13, 32, 37, 38, 39, 30 ];
  var selected = keys[ 0 ] = all[ Math.floor( Math.random() * all.length ) ];
  
  generateDOM( all, selected );
  
}

newkey();

// Add a single listener for all keypress events
document.addEventListener( 'keydown', listen );
@keyframes right {
  20% { background: green; }
}
@keyframes wrong {
  20% { background: red; }
}

.key {
  
  width: 80px;
  height: 80px;
  font-size: 20px;
  font-family: monospace;
  box-sizing: border-box;
  padding: 30px 0;
  text-align: center;
  background: lightgray;
  display: inline-block;
  
}

.selected {
  
  background: #ececec;
  
}
.wrong, .selected.wrong {

  animation: wrong 2s;
  
}
.right, .selected.right {

  animation: right 2s;
  
}
<div id="keys"></div>