多音符文本框批量升降调功能失效问题求助
批量音符升降调解决方案
核心问题分析
原代码仅处理了单个音符字符串,未对多音符的空格分隔内容进行拆分、逐个处理,导致批量场景失效。
实现思路
- 定义标准12音序列作为升降调的基准映射表
- 将textarea内容按空格拆分为独立音符数组
- 对每个音符:
- 找到其在基准序列中的索引
- 升调则索引+1,降调则索引-1,超出范围时通过取模实现循环(如si升调回到do,do降调回到si)
- 若为无效音符,直接保留原内容
- 将处理后的音符数组重新拼接为字符串,替换回textarea
完整代码示例
HTML结构
<textarea id="noteInput" rows="5" cols="50">do do# re re# mi fa fa# sol sol# la la# si</textarea> <button onclick="transposeUp()">升调(+1)</button> <button onclick="transposeDown()">降调(-1)</button>
JavaScript逻辑
// 定义标准12音序列,顺序对应半音递增 const noteSequence = ["do", "do#", "re", "re#", "mi", "fa", "fa#", "sol", "sol#", "la", "la#", "si"]; function transposeUp() { transposeNotes(1); } function transposeDown() { transposeNotes(-1); } function transposeNotes(offset) { const input = document.getElementById('noteInput'); // 按空格拆分音符,同时过滤空字符串(处理连续空格) const notes = input.value.split(' ').filter(note => note.trim() !== ''); const processedNotes = notes.map(note => { const index = noteSequence.indexOf(note); // 有效音符则计算新索引,无效则保留原内容 if (index !== -1) { // 取模12确保循环,处理负数索引(如do降调:0-1=-1 → (-1 +12)%12=11 → si) const newIndex = (index + offset + noteSequence.length) % noteSequence.length; return noteSequence[newIndex]; } return note; }); // 重新拼接为空格分隔的字符串 input.value = processedNotes.join(' '); }
关键细节说明
- 使用
split(' ')拆分音符,配合filter处理输入中的连续空格或首尾空格 - 索引计算时加上
noteSequence.length再取模,避免负数索引导致的错误(如do降调时0-1=-1,加12后为11,取模12仍为11,对应si) - 保留无效音符的原样输出,提升鲁棒性
内容的提问来源于stack exchange,提问作者Anastasia
相关产品推荐
相关产品推荐

