在按键上删除类(按键保持后),转换和奇怪的行为

时间:2017-05-05 00:59:53

标签: javascript ecmascript-6

我正在重构JS30 Challange#1。按下键时,脚本会向具有一点变换的元素添加一个类。我想在转换结束时从元素中删除类,我做了这个:

const KEYS = document.querySelectorAll('.audiobox');
KEYS.forEach(KEY => KEY.addEventListener('transitionend', function() {
  KEY.classList.remove('playing');
}), false);

此代码运行良好,但我想通过调用removeTransition函数来清理它。

function removeTransition(e) {
  if (e.propertyName !== 'transform') return;
  e.target.classList.remove('playing');
}

const KEYS = document.querySelectorAll('.audiobox');
KEYS.forEach(KEY => KEY.addEventListener('transitionend', removeTransition));

当我按下一个键脚本完成它的工作时,类在转换结束时被删除,但问题是当我按住一个键几秒钟时,类永远不会被删除。正如我所提到的,即使我拿着钥匙,第一个解决方案也能很好地工作,第二个解决方案没有完全正常工作,你能告诉我为什么吗?

这是完整的脚本

(function() {
  "use strict";

  function removeTransition(e) {
    if (e.propertyName !== 'transform') return;
    e.target.classList.remove('playing');
  }

  function playAudio(e) {
    let key_code;
    if (e.type === 'keydown') key_code = e.keyCode;
    if (e.type === 'click') key_code = e.target.getAttribute('data-key');
    const KEY   = document.querySelector('.audiobox[data-key="' + key_code + '"]');
    const AUDIO = document.querySelector('audio[data-key="' + key_code + '"]');

    if (!AUDIO) return;

    AUDIO.currentTime = 0;
    AUDIO.play();
    KEY.classList.add('playing');

    const KEYS = document.querySelectorAll('.audiobox');
    KEYS.forEach(KEY => KEY.addEventListener('transitionend', removeTransition));

    // This one is working
    // KEYS.forEach(KEY => KEY.addEventListener('transitionend', function() {
    //   KEY.classList.remove('playing');
    // }), false);
  }

  window.addEventListener('keydown', playAudio);
  const BOXES = document.querySelectorAll('.audiobox');
  BOXES.forEach(BOX => BOX.addEventListener('click', playAudio));
})();

3 个答案:

答案 0 :(得分:0)

如评论中所述,

删除removeTransition函数

中的check if (e.propertyName !== 'transform') return;
function removeTransition(e) {
 //   if (e.propertyName !== 'transform') return;
    e.target.classList.remove('playing');
  }

Working code snippet

答案 1 :(得分:0)

似乎是从Wesbos tut发来的,在那之后尝试制作钢琴时,我遇到了与您相同的问题,如果有人遇到相同的问题,请使用Settimeout函数,如下所示:

+---+---+---+---+----+
| a | b | h | i | j  |
+---+---+---+---+----+
| 1 | 2 | 8 | 9 | 10 |
+---+---+---+---+----+

答案 2 :(得分:0)

根据教程,存在 if (e.propertyName !== 'transform') return; 是因为有 6 个 transitionend 事件:

  1. 边框底部颜色
  2. border-left-color
  3. border-right-color
  4. 边框顶部颜色
  5. 盒子阴影
  6. 转化

通过在我们的代码中使用它,我们将只执行一次而不是 6 次。因此,我为删除 .playing 类所做的是添加了一个 keyup 事件侦听器,这样即使我按住键几秒钟,它仍然会删除该类。

<script>
window.addEventListener('keydown', (e) => keyFunc(e));
window.addEventListener('keyup', (e) => keyFunc(e));

function keyFunc(e){
  let dataKey = e.keyCode;
  const key = document.querySelector(`div[data-key="${dataKey}"]`);

  if(e.type == 'keyup'){
    removeClass(e, key);
  }
  else if(e.type == 'keydown') {
    playSound(e, key);
  }
}

function playSound(e, key) {
  const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);

  if (key == null) return;
  key.classList.add('playing');
  audio.currentTime = 0;
  audio.play();
}

function removeClass(e, key) {
  if (key == null) return;
  key.classList.remove('playing');
}

const div = document.querySelector("div");
div.addEventListener('transitionend', (e) => removeTransition(e));


function removeTransition(e) {
  if(e.propertyName !== 'transform') return;
    console.log(e);
    e.target.classList.remove('playing');
}

</script>