JS中获取点击播放音频的数组当前索引报错问题排查
点击音频获取数组索引时的404与播放错误修复
问题根源
你的代码存在两个核心错误:
- findIndex逻辑完全错误:
songs.findIndex(ind => ind === songs.id)的条件不成立——songs是数组,没有id属性,导致findIndex返回-1。songs[-1]为undefined,使audio.src被设为undefined,浏览器会尝试请求本地路径http://127.0.0.1:5500/undefined,触发404错误。 - 点击事件未关联歌曲数据:点击传递的
this是DOM元素,但你没有在元素上存储对应歌曲的标识,无法将点击操作和数组中的歌曲对象关联。
修复方案
最简单的方式是在渲染歌曲列表时,直接把当前歌曲的索引作为参数传给playSongs函数,无需复杂匹配即可获取对应歌曲:
修改后的关键代码
- 更新渲染函数:给
forEach添加索引参数,在onclick中传入当前歌曲的索引:
const renderSongs = () => { songs.forEach((data, index) => { // 添加index参数 playlist.innerHTML +=` <li class="flex flex-row items-center gap-2 border-b border-b-yellow-600 border-b-2 border-dashed px-3 py-4"> <div id="playlistBtn${index}" onclick="playSongs(${index})" class="flex flex-row items-center gap-3 cursor-pointer"> <div class="flex-1 flex-wrap">${data.title}</div> <div class="text-[13px] flex-none mr-2">${data.artist}</div> <div>${data.duration}</div> </div> <button id="removeBtn${index}"> <svg width="30" height="25" fill="white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"> </button> </li> `; }); }
- 更新playSongs函数:接收索引参数,直接获取对应歌曲的src并播放,同时捕获播放错误:
const playSongs = (index) => { const currentSong = songs[index]; audio.src = currentSong.src; // 捕获播放错误,避免未捕获的Promise异常 audio.play().catch(err => { console.error('播放失败:', err); }); // 此时index就是当前歌曲在数组中的索引,可直接使用 console.log('当前播放歌曲的索引:', index); }
完整修复后的代码
const allSongs = [ //Array of objects { id: 0, title: "Scratching The Surface", artist: "Quincy Larson", duration: "4:25", src: "https://cdn.freecodecamp.org/curriculum/js-music-player/scratching-the-surface.mp3", }, { id: 1, title: "Can't Stay Down", artist: "Quincy Larson", duration: "4:15", src: "https://cdn.freecodecamp.org/curriculum/js-music-player/can't-stay-down.mp3", }, { id: 2, title: "Still Learning", artist: "Quincy Larson", duration: "3:51", src: "https://cdn.freecodecamp.org/curriculum/js-music-player/still-learning.mp3", }, { id: 3, title: "Cruising for a Musing", artist: "Quincy Larson", duration: "3:34", src: "https://cdn.freecodecamp.org/curriculum/js-music-player/cruising-for-a-musing.mp3", }, { id: 4, title: "Never Not Favored", artist: "Quincy Larson", duration: "3:35", src: "https://cdn.freecodecamp.org/curriculum/js-music-player/never-not-favored.mp3", }, { id: 5, title: "From the Ground Up", artist: "Quincy Larson", duration: "3:12", src: "https://cdn.freecodecamp.org/curriculum/js-music-player/from-the-ground-up.mp3", }, { id: 6, title: "Walking on Air", artist: "Quincy Larson", duration: "3:25", src: "https://cdn.freecodecamp.org/curriculum/js-music-player/walking-on-air.mp3", }, { id: 7, title: "Can't Stop Me. Can't Even Slow Me Down.", artist: "Quincy Larson", duration: "3:52", src: "https://cdn.freecodecamp.org/curriculum/js-music-player/cant-stop-me-cant-even-slow-me-down.mp3", }, { id: 8, title: "The Surest Way Out is Through", artist: "Quincy Larson", duration: "3:10", src: "https://cdn.freecodecamp.org/curriculum/js-music-player/the-surest-way-out-is-through.mp3", }, { id: 9, title: "Chasing That Feeling", artist: "Quincy Larson", duration: "2:43", src: "https://cdn.freecodecamp.org/curriculum/js-music-player/chasing-that-feeling.mp3", }, ]; const songs = allSongs.sort((a, b) => a.title.localeCompare(b.title)); //Sorted array const audio = new Audio(); const renderSongs = () => { songs.forEach((data, index) => { playlist.innerHTML +=` <li class="flex flex-row items-center gap-2 border-b border-b-yellow-600 border-b-2 border-dashed px-3 py-4"> <div id="playlistBtn${index}" onclick="playSongs(${index})" class="flex flex-row items-center gap-3 cursor-pointer"> <div class="flex-1 flex-wrap">${data.title}</div> <div class="text-[13px] flex-none mr-2">${data.artist}</div> <div>${data.duration}</div> </div> <button id="removeBtn${index}"> <svg width="30" height="25" fill="white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"> </button> </li> `; }); } renderSongs(); const playSongs = (index) => { const currentSong = songs[index]; audio.src = currentSong.src; audio.play().catch(err => { console.error('播放失败:', err); }); console.log('当前歌曲索引:', index); }
额外可选方案
如果不想直接传递索引,也可以给DOM元素添加自定义数据属性存储歌曲ID,再通过ID匹配索引:
// 渲染时添加data属性 <div ... data-song-id="${data.id}" onclick="playSongs(this)"> // playSongs函数修改为 const playSongs = (element) => { const songId = parseInt(element.dataset.songId); const index = songs.findIndex(song => song.id === songId); const currentSong = songs[index]; audio.src = currentSong.src; audio.play().catch(err => console.error(err)); }
内容的提问来源于stack exchange,提问作者Jesse
相关产品推荐
相关产品推荐

