代码之家  ›  专栏  ›  技术社区  ›  Timur Arazmedov

如何在js中检查多次按键?

  •  0
  • Timur Arazmedov  · 技术社区  · 3 年前

    我正在尝试创建一个立方体计时器。当我按下&按住空格键,计时器应变为绿色。当我释放时,计时器应该开始运行。当我再次按下时,计时器应该停止。然后这一切都会再次发生。

    我需要检查是否:

    1. 空格键被按下。
    2. 空格键已释放。
    3. 空格键再次被按下。

    我有这个代码:

    var down = false;
    document.addEventListener('keydown', function () {
        if (event.code === 'Space') {
            if(down) return;
            down = true;
            console.log('Waiting...')
        }
    }, false);
    
    document.addEventListener('keyup', function () {
        if (event.code === 'Space') {
            down = false;
            console.log('Start')
        }
    }, false);
    
    // I need some Stop function here
    

    问题是,当我按下空格键,然后松开它并再次按下时,它会运行4个功能。但我需要跑三个不同的。然后我必须能够再次做同样的事情。

    我该怎么做?

    1 回复  |  直到 3 年前
        1
  •  2
  •   Alexander Nenashev    3 年前

    你可以使用 KeyboardEvent::repeat 要检查您是否有第一个按键按下事件:

    https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat

    还要注意 window.event 已弃用:

    https://developer.mozilla.org/en-US/docs/Web/API/Window/event

    因此,逻辑是使用有限状态自动机,并在按键时在状态之间切换。当状态更改时 transitions 对象被调用-将您的逻辑放在那里,以便在更改状态时执行:

    let state = 'stopped';
    
    const transitions = {
      waiting: state => console.log(state),
      started: state => console.log(state),
      stopped: state => console.log(state),
    };
    
    document.addEventListener('keydown', changeState);
    document.addEventListener('keyup', changeState);
    
    function changeState({code, repeat, type: action}){
    
      if(code !== 'Space' || repeat){
        return;
      }
      
      // this allows to have more event types and states in the future without cluttering
      const actions = {
        keydown: () => state === 'stopped' ? 'waiting' : 'stopped',
        keyup: () => state === 'stopped' ? state : 'started',
      };
      
      // determine the next state 
      const next = actions[action]();
      // if the next state is different, commit it to the current and execute transition
      next === state || transitions[state = next](state);
      
    }