动态创建一系列与keyup / down一起玩的振荡器

时间:2013-01-14 06:19:53

标签: javascript dom web-audio

问题在于: 在以下示例中,http://jsfiddle.net/GmgGY/2/

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

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

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

每个动态创建的div都有一个唯一的ID,但也是一个对所有这些都是通用的类。我想可能有办法选择类(synth.class)并在keyup上启动通用的oscillator.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(); 

};


}());

});

1 个答案:

答案 0 :(得分:1)

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

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

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

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