Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将相同的功能用于按键和单击事件?_Javascript_Addeventlistener - Fatal编程技术网

Javascript 如何将相同的功能用于按键和单击事件?

Javascript 如何将相同的功能用于按键和单击事件?,javascript,addeventlistener,Javascript,Addeventlistener,我正在尝试监听两种事件类型(keydown和click),并对它们执行相同的功能(切换某些音频文件的播放和暂停) keydown的事件监听器工作正常,但是当我尝试对click使用相同的功能时,什么也没有发生。将单击作为事件类型使用时,控制台日志记录音频为空 有人能解释一下吗 请注意,我只是试图用vanilla JS来实现这一点(我的代码基于Wes Bos的Javascript 30课程的第一个项目) 代码如下: function toggleSound(e) { const audi

我正在尝试监听两种事件类型(
keydown
click
),并对它们执行相同的功能(切换某些音频文件的播放和暂停)

keydown
的事件监听器工作正常,但是当我尝试对
click
使用相同的功能时,什么也没有发生。将
单击
作为事件类型使用时,控制台日志记录
音频
为空

有人能解释一下吗

请注意,我只是试图用vanilla JS来实现这一点(我的代码基于Wes Bos的Javascript 30课程的第一个项目)

代码如下:

  function toggleSound(e) {
    const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`); 
    const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
    if(!audio) return; 
    if (audio.paused) {
     audio.currentTime = 0; 
     audio.play();
     key.classList.add('playing'); 
      } else {
        audio.pause();
        key.classList.remove('playing');
      }
  };
  function removeTransition(e) {
    if(event.propertyName !== 'transform') return; 
    this.classList.remove('playing'); 
  }
  const keys = document.querySelectorAll('.key');
  keys.forEach(key => key.addEventListener('ended', removeTransition));

  window.addEventListener('keydown',  toggleSound);
  window.addEventListener('click', toggleSound);


您实际上以错误的方式添加了此侦听器, 使用以下代码时:

window.addEventListener('单击',单击声音)

您正在运行clickSound方法,在该方法中,您正在为keys数组中的每个项目添加另一个侦听器(我不知道它是什么,但我假设它是一个html元素,因为您也在它上面使用addEventListener)

要解决此问题,您可以删除此窗口。addEventListener('click',clickSound)并为键本身添加侦听器

差不多



keys.forEach(key => {
  key.addEventListener('click', e => {
    const dataKey = e.target.dataset.key;
    const audio = document.querySelector(`audio[data-key="${dataKey}"]`);

    if (!audio) return; // Just to be sure the element was found
    if (audio.paused) {
      audio.currentTime = 0;
      audio.play();
      key.classList.add('playing');
    } else {
      audio.pause();
      key.classList.remove('playing');
    }
  });
});


你在点击上绑定点击?听起来是个坏主意。因此,您单击一个元素,然后必须再次单击,因为您刚刚绑定了它。单击该对象将绑定另一个单击事件。。。。。因此,现在该键有2个单击处理程序。再次单击它,您已附加3个事件处理程序。。。。再说一遍,我现在明白了,谢谢。我遇到的问题是,除非
window
是侦听器的事件目标,否则不会发生任何事情,但同时我似乎必须循环键(它们是html元素)。这就是为什么我最终不得不单击处理程序。我已经尝试过了,但音频现在为空。我确实在按键功能中成功访问了音频,没有任何问题-我在问题中编辑了代码,因此现在它包含了它。我刚刚编辑了问题和代码,使其更简洁。