You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS中获取点击播放音频的数组当前索引报错问题排查

点击音频获取数组索引时的404与播放错误修复

问题根源

你的代码存在两个核心错误:

  1. 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错误。
  2. 点击事件未关联歌曲数据:点击传递的this是DOM元素,但你没有在元素上存储对应歌曲的标识,无法将点击操作和数组中的歌曲对象关联。

修复方案

最简单的方式是在渲染歌曲列表时,直接把当前歌曲的索引作为参数传给playSongs函数,无需复杂匹配即可获取对应歌曲:

修改后的关键代码

  1. 更新渲染函数:给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>
`;
  });
}
  1. 更新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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 23:50:59