纯HTML/CSS/JS音乐播放器:Next按钮切换时播放图标切换异常求助
音乐播放器Next/Previous按钮切换时的播放图标同步问题
我用纯HTML、CSS和JS开发了一款音乐播放器,用来巩固JS知识,参考YouTube项目实现了基础功能并加入自己的想法。现在遇到的问题是:点击底部Next/Previous按钮切换歌曲时,希望歌曲列表中当前播放歌曲的按钮显示暂停图标(fa-circle-pause),上一首的按钮恢复为播放图标(fa-circle-play),尝试多种方法没成功。
网站代码
HTML
<body> <nav> <ul class="flex"> <li class="logo"><i class="fa-brands fa-napster fa-2xl">Nolae-fy</i></li> </ul> </nav> <div class="container "> <div class="songList"></div> <h1 class="heading">Enjoy the essence of Hallyu (한류) </h1> <div> <div class="songItem flex"> <img alt=""> <span class="songName">Meaningful Stone - A Call from My Dream</span> <span class="songlistplay"><span class="timestamp">4:19 <i id="0" class="fa-solid songItemPlay fa-circle-play padding"></i></span> </div> <div class="songItem flex"> <img alt=""> <span class="songName">Paul Blanco - 믿어(Believe) (Feat. Crush)</span> <span class="songlistplay"><span class="timestamp">3:07 <i id="1" class="fa-solid songItemPlay fa-circle-play padding"></i></span> </div> <div class="songItem flex"> <img alt=""> <span class="songName">Meaningful Stone - A Call from My Dream</span> <span class="songlistplay"><span class="timestamp">4:19 <i id="2" class="fa-solid songItemPlay fa-circle-play padding"></i></span> </div> <div class="songItem flex"> <img alt=""> <span class="songName">Meaningful Stone - A Call from My Dream</span> <span class="songlistplay"><span class="timestamp">4:19 <i id="3" class="fa-solid songItemPlay fa-circle-play padding"></i></span> </div> <div class="songItem flex"> <img alt=""> <span class="songName">Meaningful Stone - A Call from My Dream</span> <span class="songlistplay"><span class="timestamp">4:19 <i id="4" class="fa-solid songItemPlay fa-circle-play padding"></i></span> </div> <div class="songItem flex"> <img alt=""> <span class="songName">Meaningful Stone - A Call from My Dream</span> <span class="songlistplay"><span class="timestamp">4:19 <i id="5" class="fa-solid songItemPlay fa-circle-play padding"></i></span> </div> <div class="songItem flex"> <img alt=""> <span class="songName">Meaningful Stone - A Call from My Dream</span> <span class="songlistplay"><span class="timestamp">4:19 <i id="6" class="fa-solid songItemPlay fa-circle-play padding"></i></span> </div> <div class="songItem flex"> <img alt=""> <span class="songName">Meaningful Stone - A Call from My Dream</span> <span class="songlistplay"><span class="timestamp">4:19 <i id="7" class="fa-solid songItemPlay fa-circle-play padding"></i></span> </div> <div class="songItem flex"> <img alt=""> <span class="songName">Meaningful Stone - A Call from My Dream</span> <span class="songlistplay"><span class="timestamp">4:19 <i id="8" class="fa-solid songItemPlay fa-circle-play padding"></i></span> </div> </div> <div class="songBanner"></div> </div> <div class="bottom flex"> <input type="range" name="range" id="myProgressBar" value="0" min="0" max="100"> <div class="icons"> <i class="fa-solid fa-2x fa-backward-step" id="previous"></i> <i id="masterPlay" class="fa-solid fa-2x fa-circle-play"></i> <i class="fa-solid fa-2x fa-forward-step" id="next"></i> </div> <div class="songInfo"> <img src="/img/sakura.gif" alt="" id="gif"><span id="masterSongName">Meaningful Stone - A Call from My Dream</span> </div> </div> <script src="script.js"></script> </body>
JS
console.log("Welcome to Nolae-fy!") let songIndex = 0 let audioElement = new Audio('song/1.mp3'); let masterPlay = document.getElementById("masterPlay"); let myProgressBar = document.getElementById("myProgressBar"); let gif = document.getElementById("gif"); let songItems = Array.from(document.getElementsByClassName('songItem')); let miniPlay= Array.from(document.getElementsByClassName('songItemPlay')); let masterSongName = document.getElementById("masterSongName"); let songs = [ {songName:"Meaningful Stone - A Call from My Dream", filePath:"song/dream.mp3",coverPath:"cover/dream.jpeg"}, {songName:"Paul Blanco - 믿어(Believe) (Feat. Crush)", filePath:"song/believe.mp3",coverPath:"cover/believe.jpeg"}, {songName:"Lexie Liu- 佳人 (Kappa Girl)", filePath:"song/kappa.mp3",coverPath:"cover/kappa.jpeg"}, {songName:"Jay Park - Need to Know", filePath:"song/needtoknow.mp3",coverPath:"cover/needtoknow.jpeg"}, {songName:"Jungkook - My Time", filePath:"song/mytime.mp3",coverPath:"cover/mytime.jpeg"}, {songName:"KAI (EXO) - 음 (Mmmh)", filePath:"song/mmmh.mp3",coverPath:"cover/mmmh.jpeg"}, {songName:"HIGH4 IU- Not Spring, Love, or ..", filePath:"song/spring.mp3",coverPath:"cover/spring.jpeg"}, {songName:"EXO 엑소 - 'Ko Ko Bop'", filePath:"song/kokobop.mp3",coverPath:"cover/kokobop.jpeg"}, {songName:"BIBI(비비)- KAZINO", filePath:"song/kazino.mp3",coverPath:"cover/kazino.jpeg"}, ] songItems.forEach((element,i)=>{ element.getElementsByTagName("img")[0].src = songs[i].coverPath; element.getElementsByClassName("songName")[0].innerText = songs[i].songName; }) masterPlay.addEventListener("click",()=>{ if(audioElement.paused || audioElement.currentTime<=0){ audioElement.play() masterPlay.classList.remove('fa-circle-play') masterPlay.classList.add('fa-circle-pause') gif.style.opacity = 1; } else{ audioElement.pause() masterPlay.classList.remove('fa-circle-pause') masterPlay.classList.add('fa-circle-play') gif.style.opacity = 0; } }) audioElement.addEventListener('timeupdate',()=>{ progress = parseInt((audioElement.currentTime/audioElement.duration)*100) myProgressBar.value = progress }) myProgressBar.addEventListener("change",()=>{ audioElement.currentTime = myProgressBar.value * audioElement.duration/100 }) const makeAllPlays = ()=>{ Array.from(document.getElementsByClassName('songItemPlay')).forEach((element)=>{ element.classList.remove('fa-circle-pause') element.classList.add('fa-circle-play') }) } Array.from(document.getElementsByClassName("songItemPlay")).forEach((element)=>{ element.addEventListener('click',(e)=>{ makeAllPlays(); songIndex = parseInt(e.target.id); e.target.classList.remove('fa-circle-play'); e.target.classList.add('fa-circle-pause'); audioElement.src = `song/${songIndex+1}.mp3`; masterSongName.innerText = songs[songIndex].songName; audioElement.currentTime = 0 ; audioElement.play(); masterPlay.classList.remove('fa-circle-play') masterPlay.classList.add('fa-circle-pause') gif.style.opacity = 1; }) }) const makeNewPlays = ()=>{ Array.from(document.getElementsByClassName('songItemPlay')).forEach((element)=>{ element.classList.remove('fa-circle-pause') element.classList.add('fa-circle-play') } document.getElementById('next').addEventListener('click',()=>{ if(songIndex>=8){ songIndex = 0 } else{ songIndex += 1 } makeNewPlays(); audioElement.src = `song/${songIndex+1}.mp3`; masterSongName.innerText = songs[songIndex].songName; audioElement.currentTime = 0 ; audioElement.play(); masterPlay.classList.remove('fa-circle-play') masterPlay.classList.add('fa-circle-pause') gif.style.opacity = 1; }) document.getElementById('previous').addEventListener('click',()=>{ if(songIndex<=0){ songIndex = 0 } else{ songIndex -= 1 } makeNewPlays(); audioElement.src = `song/${songIndex+1}.mp3`; masterSongName.innerText = songs[songIndex].songName; audioElement.currentTime = 0 ; audioElement.play(); masterPlay.classList.remove('fa-circle-play') masterPlay.classList.add('fa-circle-pause') gif.style.opacity = 1; })
网站截图

问题修复方案
问题分析
你的代码存在两个核心问题:
makeNewPlays函数语法不完整,缺少闭合的}),导致函数无法执行- 切换歌曲后,没有主动将当前歌曲对应的列表按钮切换为暂停图标
具体修复步骤
修正
makeNewPlays函数语法
直接复用已有的makeAllPlays函数(功能完全一致),删除冗余的makeNewPlays,或者修正其语法:const makeNewPlays = ()=>{ Array.from(document.getElementsByClassName('songItemPlay')).forEach((element)=>{ element.classList.remove('fa-circle-pause') element.classList.add('fa-circle-play') }) }添加当前歌曲图标切换逻辑
在Next和Previous按钮的点击事件中,调用makeAllPlays()重置所有图标后,给当前songIndex对应的按钮设置暂停图标:
Next按钮修改后代码
document.getElementById('next').addEventListener('click',()=>{ if(songIndex>=8){ songIndex = 0 } else{ songIndex += 1 } makeAllPlays(); // 设置当前歌曲按钮为暂停图标 const currentBtn = document.getElementById(songIndex); currentBtn.classList.remove('fa-circle-play'); currentBtn.classList.add('fa-circle-pause'); audioElement.src = `song/${songIndex+1}.mp3`; masterSongName.innerText = songs[songIndex].songName; audioElement.currentTime = 0 ; audioElement.play(); masterPlay.classList.remove('fa-circle-play') masterPlay.classList.add('fa-circle-pause') gif.style.opacity = 1; })
Previous按钮修改后代码
document.getElementById('previous').addEventListener('click',()=>{ if(songIndex<=0){ songIndex = 0 } else{ songIndex -= 1 } makeAllPlays(); // 设置当前歌曲按钮为暂停图标 const currentBtn = document.getElementById(songIndex); currentBtn.classList.remove('fa-circle-play'); currentBtn.classList.add('fa-circle-pause'); audioElement.src = `song/${songIndex+1}.mp3`; masterSongName.innerText = songs[songIndex].songName; audioElement.currentTime = 0 ; audioElement.play(); masterPlay.classList.remove('fa-circle-play') masterPlay.classList.add('fa-circle-pause') gif.style.opacity = 1; })
额外优化
可以把图标切换逻辑封装成单独函数,减少重复代码:
const updatePlayIcons = (currentIndex) => { makeAllPlays(); const btn = document.getElementById(currentIndex); btn.classList.remove('fa-circle-play'); btn.classList.add('fa-circle-pause'); }
之后在需要切换图标的地方直接调用updatePlayIcons(songIndex)即可。
内容的提问来源于stack exchange,提问作者Antarik Chetia
相关产品推荐
相关产品推荐

