2017-06-16 11 views
0

このコードは、オーディオ要素をランダムに再生します。 setupを2回実行すると、2つの異なるアレイでこれを同時に実行することができます。これは私が望むものです。問題は、#stopは、再生中の配列の1つだけを停止することです。これは実際には、setupを1つの配列に呼び出すだけで、#startを2回以上クリックすると発生します(これも望ましくありません)。私はこれが1つのsetIntervalにしか指定されないので、これが 'intervalReturn'と関係していると考えます。複数のsetIntervalsと1つの関数(Javascript)

setupの複数の呼び出しで一度だけ起動できる個別のsetIntervalsが作成されるようにするにはどうすればよいですか?

これとは全く別の角度からアプローチしなければならない場合は、どうすればよいでしょうか?

編集:これは以下の提案で修正されました。しかし、私は不思議に思っています、ここでsetIntervalを使って "ボンネットの下で"何が起こっているのですか?なぜこの現象はまったく起こりますか? (具体的に:。#stopは1を停止しますが、すべてではないオーディオの要素)

var CMajor3 = new Array ("C3","D3","E3","F3","G3","A3","B3","C4a"); 
var CMajor4 = new Array ("C4b","D4","E4","F4","G4","A4","B4","C5"); 

var intervalReturn = null; 

function pickAndPlay(pitchSet){ 
    fyshuffle (pitchSet); // the Fischer-Yates shuffle function 
    var tone = document.getElementById(pitchSet[0]); 
    tone.currentTime = 0; 
    tone.play();  
}; 

function setup(time, pitchSet){ 
    $("#start").click(function() { 
     console.log("startClicked"); 
     intervalReturn = window.setInterval(pickAndPlay, time, pitchSet) 
    }); 
    $("#stop").click(function() { 
     console.log("stopClicked"); 
     window.clearInterval(intervalReturn) 
    }); 
}; 

$(document).ready(function() { 
    setup(2000, CMajor3); 
    setup(2000, CMajor4); 
}); 
+2

問題は、単一の 'intervalReturn'変数が2つの異なる値を同時に保持できないことです。 - 'var intervalReturn = null'を' function setup'の最初の行に移動してみてください –

+0

コメントを編集する参照してください? –

+1

* "これは、あなたが#startを2回以上クリックした場合にも起こります。" * - あなたができることを何かしたいのですか?または、ユーザーがもう一度開始をクリックする前に前のものを停止する必要がありますか? – nnnnnn

答えて

1

しかし、私はここのsetIntervalで「フードの下」で何が起こっているか、思ったんだけど?

#start#stop要素に追加クリックハンドラを作成し、あなたがsetup()を呼び出すたびに、。実際に#start、または#stopをクリックすると、がすべて適用されます。適用ハンドラのすべてが(バインドされた同じ順序で)呼び出されます。このため、#startをクリックすると、CMajor3CMajor4ノートが再生されます。複数の同時では無関係のインターバルが実行されます。 #startクリックハンドラがそれを実行するたびに、以前のものを上書きしてしまうため、グローバル変数として定義intervalReturn

は、あなたは今まで、setInterval()への最新の呼び出しから返された間隔のIDを持っています。だから、#stopをクリックするだけで間隔の1つが止まり、他のものを止める方法はありません。道closures work in JSは、引数とsetup()、すなわち、timepitchSetintervalReturnのローカル変数は、(あなたが宣言を移動した後に)2つのイベントハンドラにアクセス可能であるということですので、setup()関数内var intervalReturn宣言ができます移動

現在の電話番号setup()で定義されています。その後のsetup()の呼び出しでは、それらの変数の独自のコピーを持つ新しいクロージャが作成されます。したがって、#stopクリックハンドラは、setup()に関連する個別のintervalReturnを使用します。 #stopハンドラが実行されるため、両方の間隔がクリアされます。

しかし、あなたはまだ#stopをクリックせずに何度も#start#多くをクリックすると、追加の間隔を作成し、個々のintervalReturnが最新で上書きされることをいずれかsetup()内なので、再び#stopが戻って、以前の間隔を参照する方法がないという問題を抱えています。これは、を追加する理由は、ハンドラがまだ実行されていない場合にのみ新しい間隔を開始することです。(。そして、あなただけclearInterval(intervalReturn)を呼び出すことintervalReturn変数の値を変更しませんので、#stopハンドラでintervalReturn = nullを追加する必要があります)

提案:以下に、既存のconsole.log()ステートメントを更新します。

console.log("startClicked", pitchSet, intervalReturn); 
// and 
console.log("stopClicked", pitchSet, intervalReturn); 

さらに、setInterval()を呼び出した直後にstartClickedを1つ追加して、の前のではなく、戻ったばかりの間隔IDを記録するようにしてください。そうすれば、関連するすべての変数の値を確認し、何が起きているのかを見ることができます。

+0

すごい!この徹底的な説明をいただき、ありがとうございます。私はこのプロジェクトを理解するために勉強する必要があることをはっきりさせています。 –

関連する問題