简体   繁体   English

整理和多个事件监听器

[英]tidying up and multiple event listeners

I´m trying to achieve a functional and DRY style of programming. 我正在尝试实现功能和干燥的编程风格。 In this case, I would need to somehow turn the "display" action into a function (which is a problem, since it makes particular outputs for every output),find a way to get rid of the global variable altogether and handle both click and keyword events at the same time to avoid the repetition of code. 在这种情况下,我需要以某种方式将“显示”动作转换为一个函数(这是一个问题,因为它为每个输出生成特定的输出),找到一种方法来完全摆脱全局变量并处理单击和关键字事件同时避免重复代码。 I can´t change the "id" tags or classes on the HTML, since they are part of the requested structure. 我无法更改HTML上的“id”标记或类,因为它们是所请求结构的一部分。 Any ideas? 有任何想法吗?

HTML HTML

<body>
    <div id="drum-machine">
        <div id="display">
            <p id="displaytext"></p>
        </div>
            <div id="controls1">
            <button id="Heater1button"  class="drum-pad"><audio class="clip" id="Q" src="https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3" preload="auto"></audio>Q</button>
            <button id="Heater2button" class="drum-pad"><audio class="clip" id='W' src="https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3" preload="auto"></audio>W</button>
            <button id="Heater3button" class="drum-pad"><audio class="clip" id='E' src="https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3" preload="auto"></audio>E</button>
            </div>
        <div id="controls2">
            <button id="Heater4button" class="drum-pad"><audio class="clip" id='A' src="https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3" preload="auto"></audio>A</button>
            <button id="Heater6button"  class="drum-pad"><audio class="clip" id='S'src="https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3"></audio>S</button>
            <button id="OpenHHbutton"  class="drum-pad"><audio class="clip" id='D'src="https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3"></audio>D</button>
        </div>
        <div id="controls3">
            <button id="KicknHat" class="drum-pad"><audio class="clip" id='Z'src="https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3"></audio>Z</button>
            <button id="Kickbutton"class="drum-pad"><audio class="clip" id='X'src="https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3"></audio>X</button>
            <button id="ClosedHHbutton"class="drum-pad"><audio class="clip" id='C' src="https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3"></audio>C</button>
        </div>
    </div>

Javascript 使用Javascript

var text1=document.getElementById("displaytext")

document.addEventListener("click",function(id) {
var id = event.target.id;
  switch (id) {
    case "Heater1button":
      document.getElementById('Q').play(), text1.textContent="Heater 1"
      break;
    case "Heater2button":
      document.getElementById('W').play(), text1.textContent="Heater 2"
      break;
    case "Heater3button":
      document.getElementById('E').play(), text1.textContent="Heater 3"
      break;
    case "Heater4button":
      document.getElementById('A').play(), text1.textContent="Heater 4"
      break;
    case "Heater6button":
      document.getElementById('S').play(), text1.textContent="Heater 6"
      break;
   case "OpenHHbutton":
    document.getElementById('D').play(), text1.textContent="Open HH"
    break;
    case "KicknHat":
      document.getElementById('Z').play(), text1.textContent="Kick N Hat"
      break;
    case "Kickbutton":
      document.getElementById('X').play(), text1.textContent="Kick"
      break;
      case "ClosedHHbutton":
      document.getElementById('C').play(), text1.textContent="Closed HH"
      break; 

  }
});


document.addEventListener("keydown",function(e){
      switch(e.keyCode){
                    case 81: document.getElementById('Q').play(),text1.textContent="Heater 1"
break;
                    case 87: document.getElementById('W').play(),text1.textContent="Heater 2"
break;
                    case 69: document.getElementById('E').play(),text1.textContent="Heater 3"
break;
                    case 65: document.getElementById('A').play(),text1.textContent="Heater 4"
break;
                    case 83: document.getElementById('S').play(),text1.textContent="Heater 6"
break;
                   case 68: document.getElementById('D').play(),text1.textContent="Open HH"
break;

                   case 90: document.getElementById('Z').play(),text1.textContent="Kick N Hat"
break;
                   case 88: document.getElementById('X').play(),text1.textContent="Kick"
break;
                   case 67: document.getElementById('C').play(),text1.textContent="Closed HH"
break;
}})

Instead of refactoring your code, I'm going to show how I would write your code from scratch. 我将展示如何从头开始编写代码,而不是重构代码。

Select the target elements by className and convert the collection into a regular array: 按className选择目标元素,并将集合转换为常规数组:

const dps = [].slice.call(document.querySelectorAll('.drum-pad'));
const dt = document.querySelector('#displaytext');

Instead of using switch statements use arrays: 而不是使用switch语句使用数组:

const texts = ["Heater 1", "Heater 2", "Heater 3", "Heater 4", "Heater 6", "Open HH", "Kick N Hat", "Kick", "Closed HH"];
const keycodes = [81, 87, 69, 65, 83, 68, 90, 88, 67];

Define a general handler for both click and keydown events and use Array.prototype.indexOf for finding the target element: clickkeydown事件定义通用处理程序,并使用Array.prototype.indexOf查找目标元素:

function handler(e) {
  const index = e.type === 'keydown' ? keycodes.indexOf(e.keyCode) : dps.indexOf(this);
  const target = dps[index];
  if (!target) return;
  const audio = target.childNodes[0];
  audio.play();
  dt.textContent = texts[index];
}

dps.forEach(function(el) {
  el.addEventListener('click', handler);
});

document.addEventListener("keydown", handler);

A demo on jsfiddle 关于jsfiddle的演示

The above solution is an attempt to make the script shorter. 上述解决方案是尝试缩短脚本。 It's not the only solution, of course. 当然,这不是唯一的解决方案。 You can also use HTML5 data-* attributes instead of arrays. 您还可以使用HTML5 data- *属性而不是数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM