我有一个我编写的和弦图应用程序,我想允许用户使用onClick处理程序转置图表的键。
我的图表看起来像这样
{C}My name is Blanket, {F}And I can run fast
括号内的和弦出现在它前面的字母上方。
我想使用javascript或jquery来执行此操作。我该如何创建这个转置按钮?任何帮助表示赞赏。提前谢谢。
修改
所以这就是我想出来的......
$('.transposeUp').click(function(){
$('.chord').each(function(){
var currentChord = $(this).text(); // gathers the chord being used
if(currentChord == $(this).text()){
var chord = $(this).text().replace("F#", "G")
}
//... the if statements continue though every chord
//but I didn't place them here to save space
});
});
所以这就是问题......
我在混音中有一个斜线和弦(G / B),它改变了转置,但因为它改变了“B”,现在和弦(G / C)与“currentChord”不同所以当它到达各自的if条件时它不会改变G.直到我在Chord最终(G / G)的位置进行了足够的转置,然后第一个“G”开始转置,使最后一个“G”保持相同。有任何想法吗?非常感谢您的知识和帮助。提前谢谢。
答案 0 :(得分:3)
使用jQuery,您可以选择绑定点击处理程序。有.click(),. delegate(),。live()等等。重现API已经告诉你的内容是没有意义的,但我可以这样说:学习如何绑定点击是整个问题的最小部分,甚至用.text()捕获和弦名称也是如此一旦你看了jQuery API,就会变得微不足道。
棘手的部分将是转置自身的逻辑。您需要掌握已有的知识(例如,从E到F只有半步;没有E#或Fb)并使其作为代码工作。
我对一般建议而不是代码示例表示道歉,但我的建议是有两个数组,一个包含锐利方面的所有和弦,一个包含所有和弦的和弦。
你也可以做一些作弊:而不是将逻辑包裹到开头(比如说,位置0中的C),只需重复你的数组:
[ “C”, “C#”, “d”, “d#”, “E”, “F”, “F#”, “G”, “G#”, “A”, “B”,“C ”, “C#”, “d”, “d#”, “E”, “F”, “F#”, “G”, “G#”, “A”, “B”]
然后找到第一个出现的和弦名称,向前移动所需的停止次数,你仍然会有正确的字符串。
答案 1 :(得分:3)
您需要按顺序匹配和弦,以便一次更新一个。如果你试图一次匹配所有内容,你会遇到像你所描述的问题,因为你一遍又一遍地匹配相同的和弦。
实现此目的的一个好方法是使用正则表达式来解析和分割和弦。获得匹配的和弦值后,使用和弦数组找到要转置的下一个/上一个和弦。以下是我作为演示开发的一些示例代码:
<p><span class="chord">{C}</span>My name is Blanket,</p>
<p><span class="chord">{G / B}</span>And I can run fast</p>
<p>
<input id="transposeDown" type="button" value="Down" /> |
<input id="transposeUp" type="button" value="Up" />
</p>
var match;
var chords =
['C','C#','D','Eb','E','F','F#','G','Ab','A','Bb','B','C',
'Db','D','D#','E','F','Gb','G','G#','A','A#','C'];
var chordRegex = /C#|D#|F#|G#|A#|Db|Eb|Gb|Ab|Bb|C|D|E|F|G|A|B/g;
$('#transposeUp').click(function() {
$('.chord').each(function() {
var currentChord = $(this).text();
var output = "";
var parts = currentChord.split(chordRegex);
var index = 0;
while (match = chordRegex.exec(currentChord))
{
var chordIndex = chords.indexOf(match[0]);
output += parts[index++] + chords[chordIndex+1];
}
output += parts[index];
$(this).text(output);
});
});
$('#transposeDown').click(function() {
$('.chord').each(function() {
var currentChord = $(this).text();
var output = "";
var parts = currentChord.split(chordRegex);
var index = 0;
while (match = chordRegex.exec(currentChord))
{
var chordIndex = chords.indexOf(match[0],1);
output += parts[index++] + chords[chordIndex-1];
}
output += parts[index];
$(this).text(output);
});
});
示例演示: http://jsfiddle.net/4kYQZ/2/
有几点需要注意:
C#
与C
匹配时不匹配。C
,这样我就可以从任何位置开始并移动两个方向而不通过数组的末尾。为了实现这一点,transposeDown代码在调用chords.indexOf
时有一个额外的参数从位置1开始,因此它匹配数组中的最后一个C
而不是第一个C
。然后,当它试图移动到前一个元素时,它不会传递数组的开头。希望这有帮助!
更新1:根据OP的评论,pre-ie9不支持在数组上使用indexOf
。这可以通过使用执行相同操作的辅助函数来解决:
function arrayIndexOf(arr, match)
{
for (var i = 0; i < arr.length; i++)
if (arr[i] == match)
return i;
return -1;
}
这一行
var chordIndex = chords.indexOf(match[0]);
将替换为:
var chordIndex = arrayIndexOf(chords, match[0]);
请参阅更新的示例演示:http://jsfiddle.net/4kYQZ/11/
答案 2 :(得分:1)
调用函数转置为up:
text = transpose(text, 1);
调用功能转置为down:
text = transpose(text, -1);
功能:
function transpose(text, amount){
var lines = new Array();
var chord = new Array();
var scale = ["C","Cb","C#","D","Db","D#","E","Eb","E#","F","Fb","F#","G","Gb","G#",
"A","Ab","A#","B","Bb","B#"];
var transp = ["Cb","C","C#","Bb","Cb","C","C","C#","D","Db","D","D#","C","Db","D",
"D","D#","E","Eb","E","F","D","Eb","E","E","E#","F#","E","F","F#",
"Eb","Fb","F","F","F#","G","Gb","G","G#","F","Gb","G","G","G#","A",
"Ab","A","A#", "G","Ab","A","A","A#","B","Bb","B","C","A","Bb","B",
"B","B#","C#"];
var inter = '';
var mat = '';
lines = text.split("\n");
for(var i in lines){
if(i%2===0){
chord = lines[i].split(" ");
for(var x in chord){
if(chord[x]!==""){
inter = chord[x];
var subst = inter.match(/[^b#][#b]?/g);
for(var ax in subst){
if(scale.indexOf(subst[ax])!==-1){
if(amount>0){
for(ix=0;ix<amount;ix++){
var pos = scale.indexOf(subst[ax]);
var transpos = 3*pos-2+3;
subst[ax] = transp[transpos+1];
}
}
if(amount<0){
for(ix=0;ix>amount;ix--){
var pos = scale.indexOf(subst[ax]);
var transpos = 3*pos-2+3;
subst[ax] = transp[transpos-1];
}
}
}
}
chord[x]=subst.join("");
}
}
lines[i] = chord.join(" ");
}
}
return lines.join("\n");
}
第一行是转置,第二行不是,顺序。