在keydown()和Web Audio API上触发的事件太多
问题描述:
我正在制作一个合成器,我试图完成的是一个振荡器将被创建一次,然后按键然后在关键帧上停止。在keydown()和Web Audio API上触发的事件太多
以下是我的代码。
$(document).on("keydown", e => {
console.log(e);
let key = $("div[data-key-id = " + e.keyCode + "]")
key.addClass('red')
if (fired) return null;
fired = true;
let oscs = playTone($(key[0]).attr("data-frequency"))
if (!oscs) return null;
$(document).on('keyup', e => {
oscs.forEach(osc => {
osc.stop();
});
$('.key').removeClass('red')
fired = false;
})
})
这里被称为普雷通公司的功能。
function playTone(freq) {
if (!freq) return null;
let osc = audioCtx.createOscillator();
let osc2 = audioCtx.createOscillator();
connectNodes(osc, osc2)
osc.type = type;
osc2.type = type2;
osc.detune.value = detune * 5;
osc2.detune.value = -detune * 5;
let number = parseFloat(freq.match(/[\d\.]+/))
osc.frequency.value = number * octave;
osc2.frequency.value = number * octave;
console.log(osc)
osc.start();
console.log(osc2)
osc2.start();
return [osc,osc2]
}
正在发生的事情是,在的keydown,正在触发事件多次,这个叫普雷通公司多次。正在创建的振荡器数量超载了我的CPU并导致音频失真。我需要一种方法来确保事件只被触发一次。我试图使用已打开的变量来实现这一点,但我没有达到我需要的结果。
答
尽量确保你只一次事件绑定:
$(document).unbind('keydown.namespace').bind('keydown.namespace', e => {
console.log(e);
let key = $("div[data-key-id = " + e.keyCode + "]")
key.addClass('red')
if (fired) return null;
fired = true;
let oscs = playTone($(key[0]).attr("data-frequency"))
if (!oscs) return null;
$(document).unbind('keyup.namespace').bind('keyup.namespace', e => {
oscs.forEach(osc => {
osc.stop();
});
$('.key').removeClass('red')
fired = false;
})
})
你在你的'keydown'事件'$(文件)。在('keyup'',这将在每次触发keydown事件时创建一个新的单独的keyup事件处理程序。 –
这是一个很好的观点,谢谢,但我仍然有同样的问题。 – John