JavaScript:在不使用onkeyup的情况下检查何时未按下按钮

时间:2018-06-08 09:50:15

标签: javascript css-animations

我有一个任务:

  1. 点击按钮
  2. 运行动画
  3. 按住按钮只运行一次动画
  4. 只使用“onKeyDown”设备支持的唯一dom事件
  5. 在这里你可以看到我如何做到这一点的例子:

    let timer = null;
    let isPressed = false;
    
    const runAnimation = () => {
        div.classList.remove('run-animation');
        void div.offsetWidth;
        div.classList.add('run-animation');
    }
    
    const fillDiv = () => {
      if (!isPressed) {
        isPressed = true;
        runAnimation();
      }
    
      clearTimeout(timer);
      timer = setTimeout(() => {
        isPressed = false;
      }, 50);
    };
    
    document.onkeydown = function() {
      fillDiv();
    }
    

    Working example

    但问题在于,按住按钮时,动画会播放两次

    有没有解决方法如何避免第二次运行动画?

2 个答案:

答案 0 :(得分:0)

您可以使用animationend event

const div = document.getElementById('test');
let timer = null;
let isPressed = false;
let isRunning = false

const runAnimation = () => {
    isRunning = true;
    div.classList.remove('run-animation');
    void div.offsetWidth;
    div.classList.add('run-animation');
}

const fillDiv = () => {
   if (!isPressed) runAnimation();  
};

document.onkeydown = function() {
  if (!isRunning) fillDiv();
    isPressed = true;
}
document.onkeyup = function() {
  isPressed = false;
}

 div.addEventListener("animationend", function(){
   console.log("animationend") 
   isRunning = false;
 });
@-webkit-keyframes runAnimation {
   from { background-color: green; }
     to { background-color: white; }
}

.run-animation {
  -webkit-animation: runAnimation 1.5s ease;
	-webkit-animation-fill-mode: forwards;
}

.center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

#test {
  padding: 10px 17px;
  display: inline-block;
  border-radius: 5px;
  margin: 0 auto;
}

.text {
  font-size: 26pt;
}
<div id="test" class="center">
  <div class="text">
    Text
  </div>
</div>

答案 1 :(得分:0)

好的,这是一种查找键是否被按下的方法。 keydown事件对象包含一个名为repeat的属性。

  

如果按键被按下足够长的时间以触发按键重复,则为;否则,错误。

我们可以检查一下。如果这是真的,我们可以在不做任何事情的情况下返回,否则我们可以启动fillDiv函数。

我已经规定了不再需要的所有位,例如isPressedtimer

为了使其成功,我必须在您的事件监听器中将e作为参数传递,我使用e来表示event

&#13;
&#13;
const div = document.getElementById('test');

const runAnimation = () => {
  div.classList.remove('run-animation');
  void div.offsetWidth;
  div.classList.add('run-animation');
}

const fillDiv = () => {
  runAnimation();
};

document.onkeydown = (e) => {
  if (e.repeat) return;
  fillDiv();
}
&#13;
@-webkit-keyframes runAnimation {
  from {
    background-color: green;
  }
  to {
    background-color: white;
  }
}

.run-animation {
  -webkit-animation: runAnimation 1.5s ease;
  -webkit-animation-fill-mode: forwards;
}

.center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

#test {
  padding: 10px 17px;
  display: inline-block;
  border-radius: 5px;
  margin: 0 auto;
}

.text {
  font-size: 26pt;
}
&#13;
<div id="test" class="center">
  <div class="text">
    Text
  </div>
</div>
&#13;
&#13;
&#13;

我希望你觉得这很有用。