0

问题是这样的:在下面的例子中, http: //jsfiddle.net/GmgGY/2/

当您单击橙色按钮时,它会创建一个新的 div。当你点击这个 div 时,它会播放一个振荡器。如果您在键盘上按下一个键(keydown),它也会播放它。然后当键盘字符被抬起(keyup)时它会停止播放。这很好,也是我想要的。

但是,当您多次单击橙色按钮并创建多个合成器时。当您在键盘上按下一个键时,它们都会播放(这就是我想要的),但只有最后一个创建的键似乎响应 keyup 事件。我希望它们都响应 keyup 事件。不仅仅是最后一个.

我不知道如何解决这个问题。

每个动态创建的 div 都有一个唯一的 ID,但也有一个通用的类。我认为可能有一种方法可以选择类(synth.class)并在 keyup 上启动通用振荡器.disconnect() ???

我在想的另一件事是我的问题可能需要某种迭代线程来补偿导致此问题的任何 DOM 问题(假设它不仅仅是迄今为止的编程)。但我不确定。

Javascript代码如下。我试图让它尽可能小,但我不知道如何使它比这更小并且仍然很清楚。我省略了 html 和 css 元素,但将它们保留在 JSfiddle 示例中。

$(function(){

var SynthCreationModule = (function(){   
context = new webkitAudioContext(); 
var orangeButton;
var applicationArea = document.getElementById("applicationArea"),
orangeButton = document.getElementById("orangeButton"),         
counterSynth = 1;
counterPitchInput = 1;
orangeButton.addEventListener("click",createSynth, false); 



function createSynth () {
  var synth = document.createElement("div"); 
  synth.className  = "synth";                         
  synth.id = "synthid" + (counterSynth++);
  applicationArea.appendChild(synth);
  var pitchInput = document.createElement('input');
  pitchInput.type = "range";
  pitchInput.className  = "pitchInputClass";
  pitchInput.id = "pitchInput" + (counterPitchInput++);
  pitchInput.min = "0";
  pitchInput.max="2000";
  synth.appendChild(pitchInput);



synth.onmousedown= function () {
   oscillator = context.createOscillator(),  
   oscillator.type = 2;  
   oscillator.frequency.value = pitchInput.value;                   
   oscillator.connect(context.destination);  
   oscillator.noteOn(0); 


};



synth.onmouseup = function ()    {  
oscillator.disconnect(); 

};


// Keydown & keyup events to launch oscillator. ( These don't work properly if you create two or more synths. Playing a key down works, but keyup only works on the last created synth. The previous created synths will continue to create additional oscillators but the keydown will not work to stop them.

var keydown = false;

$('body').keydown(function() {
    if(!keydown){
        synth.onmousedown();
        keydown = true;
    }
});

$('body').keyup(function() {
    synth.onmouseup();
    keydown = false;
});


$(synth).draggable(); 

};


}());

});
4

1 回答 1

1

您的问题实际上是您从未明确声明和范围“振荡器” - 所以它进入了全局变量。试着把“这个”。在每次出现“振荡器”之前,它都会起作用。

但是,这不是理想的代码,因为您为每个合成器附加了一个额外的主体事件处理程序 - 您的代码

$('body').keydown(function() {
    if(!keydown){
        synth.onmousedown();
        keydown = true;
    }
});

正在创建一个完整的单独函数调用并在引擎盖下的主体上调用 attachEventHandler,“合成器”绑定到新版本;跟踪合成器列表(甚至从 body.getElementsBySelector() 中获取它们)并在每​​个合成器上调用 noteOn/Off 可能会更好。不过,由你决定。

于 2013-01-14T21:47:26.667 回答