![](/img/trans.png)
[英]attributeChangedCallback() always called twice ending up with multiple event listeners
[英]tidying up and multiple event listeners
我正在尝试实现功能和干燥的编程风格。 在这种情况下,我需要以某种方式将“显示”动作转换为一个函数(这是一个问题,因为它为每个输出生成特定的输出),找到一种方法来完全摆脱全局变量并处理单击和关键字事件同时避免重复代码。 我无法更改HTML上的“id”标记或类,因为它们是所请求结构的一部分。 有任何想法吗?
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
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;
}})
我将展示如何从头开始编写代码,而不是重构代码。
按className选择目标元素,并将集合转换为常规数组:
const dps = [].slice.call(document.querySelectorAll('.drum-pad'));
const dt = document.querySelector('#displaytext');
而不是使用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];
为click
和keydown
事件定义通用处理程序,并使用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);
上述解决方案是尝试缩短脚本。 当然,这不是唯一的解决方案。 您还可以使用HTML5 data- *属性而不是数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.