点击按钮无法对应播放数组中音频文件的技术求助
解决按钮绑定点击事件播放对应索引音频的问题
原代码的问题分析
- 语法错误:
drum函数中的for循环写法错误,正确格式应为for (初始化; 条件; 递增),你写成了for (var i = 0; i < drumSound.length, i++;),把分号误写为逗号,还多了一个冗余分号,直接导致语法报错。 - 循环体范围错误:循环体未用大括号
{}包裹,只有var c = new Audio(drumSound[i]);属于循环内容,c.play()会在循环结束后仅执行一次,此时i等于drumSound.length,drumSound[i]为undefined,无法创建有效Audio对象。 - 逻辑偏差:你的需求是点击第i个按钮播放对应索引的音频,但原代码在点击事件里循环播放所有音频,完全偏离需求逻辑。
正确解决方案
方案1:使用let块级作用域(推荐,ES6+)
利用let在循环中的块级作用域特性,每个迭代的i值会被单独捕获,点击时可直接获取对应按钮的索引:
const buttons = document.querySelectorAll("button"); const drumSound = ["sounds\\crash.mp3", "sounds\\kick-bass.mp3", "sounds\\snare.mp3", "sounds\\tom-1.mp3", "sounds\\tom-2.mp3", "sounds\\tom-3.mp3", "sounds\\tom-4.mp3"]; for (let i = 0; i < buttons.length; i++) { buttons[i].addEventListener("click", function() { const audio = new Audio(drumSound[i]); audio.play(); }); }
方案2:使用闭包(兼容ES5及以下)
若需兼容旧环境,用立即执行函数创建闭包保存每个迭代的索引值:
var buttons = document.querySelectorAll("button"); var drumSound = ["sounds\\crash.mp3", "sounds\\kick-bass.mp3", "sounds\\snare.mp3", "sounds\\tom-1.mp3", "sounds\\tom-2.mp3", "sounds\\tom-3.mp3", "sounds\\tom-4.mp3"]; for (var i = 0; i < buttons.length; i++) { (function(index) { buttons[index].addEventListener("click", function() { var audio = new Audio(drumSound[index]); audio.play(); }); })(i); }
方案3:使用forEach遍历(简洁写法)
用forEach直接遍历按钮元素,同时获取对应索引:
const buttons = document.querySelectorAll("button"); const drumSound = ["sounds\\crash.mp3", "sounds\\kick-bass.mp3", "sounds\\snare.mp3", "sounds\\tom-1.mp3", "sounds\\tom-2.mp3", "sounds\\tom-3.mp3", "sounds\\tom-4.mp3"]; buttons.forEach((btn, index) => { btn.addEventListener("click", () => { const audio = new Audio(drumSound[index]); audio.play(); }); });
内容的提问来源于stack exchange,提问作者Shaker
相关产品推荐
相关产品推荐

