我正在尝试让网页在 Q、W、E、R 和 T 按键上播放鼓声音频。音频存储在 React 状态对象中:
const [sounds, setSounds] = useState({
loadState: false,
Q : "",
W : "",
E : "",
R : "",
T : ""
})
并且将被更新为几个常量之一,代表稍后显示的按钮控制的不同样式:
function makeAudioObj(genre) {
return ({
loadState: true,
Q : new Audio(`/audio/${genre}/${genre}_kick.wav`),
W : new Audio(`/audio/${genre}/${genre}_snare.wav`),
E : new Audio(`/audio/${genre}/${genre}_hat.wav`),
R : new Audio(`/audio/${genre}/${genre}_cymbal.wav`),
T : new Audio(`/audio/${genre}/${genre}_misc.wav`)
})
}
const rnbAudio = makeAudioObj('rnb');
const hiphopAudio = makeAudioObj('hiphop');
const jazzAudio = makeAudioObj('jazz');
const electronicAudio = makeAudioObj('electronic');
按键功能添加为:
function pressKey(e) {
let key = e.key.toUpperCase();
if (sounds.loadState) {
sounds[key].play();
}
}
function setListener() {
document.addEventListener('keypress', pressKey);
}
function resetListener() {
document.removeEventListener('keypress', pressKey);
}
最后,这被打包成一个由处理样式更改的按钮执行的函数:
const [firstLoad, setFirstLoad] = useState(false) // necessary to prevent removal of EventListener before it exists
function kitSelection(genre, event) {
if (firstLoad) {
resetListener();
}
setSounds(genre);
setListener();
if (!firstLoad) {
setFirstLoad(true);
}
}
return (
<div>
<button onClick={e => kitSelection(rnbAudio, e)}>{'R&B'}</button>
<button onClick={e => kitSelection(hiphopAudio, e)}>Hip-Hop</button>
<button onClick={e => kitSelection(jazzAudio, e)}>Jazz</button>
<button onClick={e => kitSelection(electronicAudio, e)}>Electronic</button>
</div>
)
问题是 removeEventListener 不起作用,但与我发现的本网站上的其他帖子不一致。我认为这个问题与 pressKey
引用一个事件有关,这意味着它试图删除一个与设置不同的函数。但是,尽管以相同的方式引用 pressKey
,但将这些相同的 setListener/resetListener 函数放入页面其他位置的按钮表单中(例如,处理添加和删除 EventListener 的按钮)确实有效。这让我对我实施这个错误的方式感到困惑。此外,如果这确实是问题所在,我不知道如何在不引用事件的情况下实现像我所追求的功能。