如何在 if, else 条件中正确使用 event.code 和 event.button?
How to use event.code and event.button in if, else condition properly?
我的目标是使用 vanilla Javascript 构建演奏鼓,当我只使用 keydown
事件时,整个代码工作完美,不幸的是,我的鼓也必须在鼠标上演奏 'click'.
当我将 "|| event.button == aKey == 0"
这部分添加到我的条件时,它仍然播放,但每个键上只有一个声音。所以我假设我的情况有问题。
而且,如果有可能以某种方式降低我的代码的可重复性,我将不胜感激。
const aKey = document.getElementById("A-key");
const sKey = document.getElementById("S-key");
const dKey = document.getElementById("D-key");
const fKey = document.getElementById("F-key");
const gKey = document.getElementById("G-key");
const hKey = document.getElementById("H-key");
const jKey = document.getElementById("J-key");
const kKey = document.getElementById("K-key");
const lKey = document.getElementById("L-key");
const playFunction = (event) => {
if (event.code == "KeyA" || event.button == aKey == 0) {
//
let audioA = document.createElement("AUDIO");
if (audioA.canPlayType("audio/wav")) {
audioA.setAttribute("src","sounds/boom.wav");
}
audioA.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioA);
} else if (event.code == "KeyS" || event.button == sKey == 0 ) {
let audioS= document.createElement("AUDIO");
if (audioS.canPlayType("audio/wav")) {
audioS.setAttribute("src","sounds/clap.wav");
}
audioS.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioS);
} else if (event.code == "KeyD" || event.button == dKey == 0) {
let audioD = document.createElement("AUDIO");
if (audioD.canPlayType("audio/wav")) {
audioD.setAttribute("src","sounds/hihat.wav");
}
audioD.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioD);
} else if (event.code == "KeyF" || event.button == fKey == 0) {
let audioF = document.createElement("AUDIO");
if (audioF.canPlayType("audio/wav")) {
audioF.setAttribute("src","sounds/kick.wav");
}
audioF.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioF);
} else if (event.code == "KeyG" || event.button == gKey == 0) {
let audioG = document.createElement("AUDIO");
if (audioG.canPlayType("audio/wav")) {
audioG.setAttribute("src","sounds/openhat.wav");
}
audioG.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioG);
} else if (event.code == "KeyH" || event.button == hKey == 0) {
let audioH = document.createElement("AUDIO");
if (audioH.canPlayType("audio/wav")) {
audioH.setAttribute("src","sounds/ride.wav");
}
audioH.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioH);
} else if (event.code == "KeyJ" || event.button == jKey == 0) {
let audioJ = document.createElement("AUDIO");
if (audioJ.canPlayType("audio/wav")) {
audioJ.setAttribute("src","sounds/snare.wav");
}
audioJ.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioJ);
} else if (event.code == "KeyK" || event.button == kKey == 0) {
let audioK = document.createElement("AUDIO");
if (audioK.canPlayType("audio/wav")) {
audioK.setAttribute("src","sounds/tink.wav");
}
audioK.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioK);
} else if (event.code == "KeyL" || event.button == lKey == 0) {
let audioL = document.createElement("AUDIO");
if (audioL.canPlayType("audio/wav")) {
audioL.setAttribute("src","sounds/tom.wav");
}
audioL.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioL);
} else {
console.log("Try to use specified keys.")
}
};
window.addEventListener('keydown', playFunction, false);
window.addEventListener('click', playFunction, false);
event.button == kKey == 0
没有多大意义。其计算结果类似于 (foo == bar) == baz
,即测试第一个条件,然后根据另一个条件检查该条件的结果(真或假)。如果要测试多个条件,请在每个条件之间使用 ||
或 &&
。此外,始终使用 ===
以避免意外的转换行为。
至于重构请求,只要你有一堆仅基于可参数化值不同的分支,如按钮文本或声音,请使用数组或对象等数据结构和 index/key进去。
具体来说,您在这里只需要密钥 -> 音频或音频 URL 对,因此对象似乎合适。
一旦你有了这样的结构,你就可以利用循环的力量来DRY你的代码。
我没有你的音频文件或标记,因此你可以尝试将此概念验证应用到你的项目中:
const baseURL = `https://upload.wikimedia.org/wikipedia/commons/`;
const sounds = {
a: `7/7c/Bombo_Leg%C3%BCero_Grave.ogg`,
s: `7/7f/Bombo_Ac%C3%BAstico.ogg`,
d: `3/35/Bongo_Agudo.ogg`,
f: `4/44/Bongo_Grave.ogg`,
g: `b/b4/Sting.ogg`,
// ... add more key-sound URL pairs ...
};
Object.keys(sounds).forEach(key => {
const btn = document.createElement("button");
document.querySelector("#drum-pad").appendChild(btn);
const sound = new Audio(baseURL + sounds[key]);
sounds[key] = sound;
btn.textContent = key;
btn.addEventListener("click", e => {
sound.currentTime = 0;
sound.play();
});
});
document.addEventListener("keydown", e => {
if (sounds[e.key]) {
sounds[e.key].currentTime = 0;
sounds[e.key].play();
}
});
<div id="drum-pad"></div>
我的目标是使用 vanilla Javascript 构建演奏鼓,当我只使用 keydown
事件时,整个代码工作完美,不幸的是,我的鼓也必须在鼠标上演奏 'click'.
当我将 "|| event.button == aKey == 0"
这部分添加到我的条件时,它仍然播放,但每个键上只有一个声音。所以我假设我的情况有问题。
而且,如果有可能以某种方式降低我的代码的可重复性,我将不胜感激。
const aKey = document.getElementById("A-key");
const sKey = document.getElementById("S-key");
const dKey = document.getElementById("D-key");
const fKey = document.getElementById("F-key");
const gKey = document.getElementById("G-key");
const hKey = document.getElementById("H-key");
const jKey = document.getElementById("J-key");
const kKey = document.getElementById("K-key");
const lKey = document.getElementById("L-key");
const playFunction = (event) => {
if (event.code == "KeyA" || event.button == aKey == 0) {
//
let audioA = document.createElement("AUDIO");
if (audioA.canPlayType("audio/wav")) {
audioA.setAttribute("src","sounds/boom.wav");
}
audioA.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioA);
} else if (event.code == "KeyS" || event.button == sKey == 0 ) {
let audioS= document.createElement("AUDIO");
if (audioS.canPlayType("audio/wav")) {
audioS.setAttribute("src","sounds/clap.wav");
}
audioS.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioS);
} else if (event.code == "KeyD" || event.button == dKey == 0) {
let audioD = document.createElement("AUDIO");
if (audioD.canPlayType("audio/wav")) {
audioD.setAttribute("src","sounds/hihat.wav");
}
audioD.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioD);
} else if (event.code == "KeyF" || event.button == fKey == 0) {
let audioF = document.createElement("AUDIO");
if (audioF.canPlayType("audio/wav")) {
audioF.setAttribute("src","sounds/kick.wav");
}
audioF.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioF);
} else if (event.code == "KeyG" || event.button == gKey == 0) {
let audioG = document.createElement("AUDIO");
if (audioG.canPlayType("audio/wav")) {
audioG.setAttribute("src","sounds/openhat.wav");
}
audioG.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioG);
} else if (event.code == "KeyH" || event.button == hKey == 0) {
let audioH = document.createElement("AUDIO");
if (audioH.canPlayType("audio/wav")) {
audioH.setAttribute("src","sounds/ride.wav");
}
audioH.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioH);
} else if (event.code == "KeyJ" || event.button == jKey == 0) {
let audioJ = document.createElement("AUDIO");
if (audioJ.canPlayType("audio/wav")) {
audioJ.setAttribute("src","sounds/snare.wav");
}
audioJ.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioJ);
} else if (event.code == "KeyK" || event.button == kKey == 0) {
let audioK = document.createElement("AUDIO");
if (audioK.canPlayType("audio/wav")) {
audioK.setAttribute("src","sounds/tink.wav");
}
audioK.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioK);
} else if (event.code == "KeyL" || event.button == lKey == 0) {
let audioL = document.createElement("AUDIO");
if (audioL.canPlayType("audio/wav")) {
audioL.setAttribute("src","sounds/tom.wav");
}
audioL.setAttribute("autoplay", "autoplay");
document.body.appendChild(audioL);
} else {
console.log("Try to use specified keys.")
}
};
window.addEventListener('keydown', playFunction, false);
window.addEventListener('click', playFunction, false);
event.button == kKey == 0
没有多大意义。其计算结果类似于 (foo == bar) == baz
,即测试第一个条件,然后根据另一个条件检查该条件的结果(真或假)。如果要测试多个条件,请在每个条件之间使用 ||
或 &&
。此外,始终使用 ===
以避免意外的转换行为。
至于重构请求,只要你有一堆仅基于可参数化值不同的分支,如按钮文本或声音,请使用数组或对象等数据结构和 index/key进去。
具体来说,您在这里只需要密钥 -> 音频或音频 URL 对,因此对象似乎合适。
一旦你有了这样的结构,你就可以利用循环的力量来DRY你的代码。
我没有你的音频文件或标记,因此你可以尝试将此概念验证应用到你的项目中:
const baseURL = `https://upload.wikimedia.org/wikipedia/commons/`;
const sounds = {
a: `7/7c/Bombo_Leg%C3%BCero_Grave.ogg`,
s: `7/7f/Bombo_Ac%C3%BAstico.ogg`,
d: `3/35/Bongo_Agudo.ogg`,
f: `4/44/Bongo_Grave.ogg`,
g: `b/b4/Sting.ogg`,
// ... add more key-sound URL pairs ...
};
Object.keys(sounds).forEach(key => {
const btn = document.createElement("button");
document.querySelector("#drum-pad").appendChild(btn);
const sound = new Audio(baseURL + sounds[key]);
sounds[key] = sound;
btn.textContent = key;
btn.addEventListener("click", e => {
sound.currentTime = 0;
sound.play();
});
});
document.addEventListener("keydown", e => {
if (sounds[e.key]) {
sounds[e.key].currentTime = 0;
sounds[e.key].play();
}
});
<div id="drum-pad"></div>