使用 javascript 或 jquery 移调音乐

Jua*_*les 3 javascript jquery

我有一个我编写的和弦图表应用程序,我希望允许用户使用 onClick 处理程序移调图表的键。

我的图表看起来像这样

{C}My name is Blanket, {F}And I can run fast
Run Code Online (Sandbox Code Playgroud)

括号内的和弦出现在它前面的字母上方。

我想使用 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
    });
});
Run Code Online (Sandbox Code Playgroud)

所以问题来了……

我在混音中有一个斜线和弦(G/B),它改变了移调但因为它改变了“B”,和弦现在是(G/C),它与“currentChord”不同,所以它不会当 G 达到其各自的 if 条件时,不要更改 G。直到我在和弦最终(G / G)的位置移调了足够多的位置,然后第一个“G”开始移调,而最后一个“G”保持不变。有任何想法吗?再次感谢您的知识和帮助。提前致谢。

mel*_*okb 5

您需要按顺序匹配和弦,以便一次更新一个和弦。如果您尝试一次匹配所有内容,则会遇到您所描述的问题,因为您一遍又一遍地匹配同一个和弦。

实现这一点的一个好方法是使用正则表达式来解析和拆分和弦。获得匹配的和弦值后,使用和弦数组查找要移调的下一个/上一个和弦。这是我作为演示开发的一些示例代码:

<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);
    });
});
Run Code Online (Sandbox Code Playgroud)

示例演示: http : //jsfiddle.net/4kYQZ/2/

需要注意的几点:

  1. 我采用了@gregp 的想法,即拥有多个键列表副本,这样我就可以同时处理锐角和平面。第一个音阶包括将在转调期间使用的首选 #/b。第二个音阶包含其他格式,因此如果音乐包含它们,它们将正确移调。例如,由于 Eb 处于第一个音阶,因此在您上下移调时将使用它而不是 D#;但是,如果音乐中以 D# 开头,它将正确地移动到 D/E(需要注意的是,如果您向后移动,它将再次变为 Eb)。随意修改首选音阶 - 我根据个人音乐经验使用了我的受过教育的判断。
  2. 正则表达式必须首先具有锐化/扁平化的键,否则 aC#将与C不正确时的a 一样容易匹配。
  3. C在数组的开头和结尾都有,这样我就可以从任何位置开始并在不经过数组末尾的情况下向两个方向移动。为了使其工作, transposeDown 代码在调用中具有一个额外的参数chords.indexOf以从位置 1 开始,因此它匹配C数组中的最后一个而不是第一个C。然后当它尝试移动到前一个元素时,它不会传递数组的开头。
  4. 我也在使用正则表达式拆分和弦,这是多余的,但它使重新组合最终字符串变得非常容易 - 通过将原始字符串部分与更新的和弦键交错(不要忘记最后一个最后一块!)。
  5. 我正在为您的按钮使用元素而不是类。

希望这可以帮助!


更新 1:根据 OP 的评论indexOf,pre-ie9 不支持对数组的使用。这可以通过使用执行相同操作的辅助函数来解决:

function arrayIndexOf(arr, match)
{
    for (var i = 0; i < arr.length; i++)
        if (arr[i] == match)
            return i;
    return -1;
}
Run Code Online (Sandbox Code Playgroud)

而这一行

var chordIndex = chords.indexOf(match[0]);
Run Code Online (Sandbox Code Playgroud)

将替换为:

var chordIndex = arrayIndexOf(chords, match[0]);
Run Code Online (Sandbox Code Playgroud)

查看更新的示例演示:http : //jsfiddle.net/4kYQZ/11/