JavaScript阻止多音频同时播放及.paused属性使用问题排查
问题:无法通过.paused属性检测歌曲播放状态
我正在不借助教程开发一款迷你音乐应用,目前实现了点击歌曲名称播放歌曲的功能,构建了对象数组及播放函数,但无法在if条件中使用.paused属性检测是否有歌曲正在播放。
const btns = Array.from(document.querySelectorAll('.song-details')); const music = [ { img: 'img/2.jpg', id:1, songName: 'Am I Wrong', audio : new Audio('audio/Am-I-wrong.mp3'), lyrics: 'Am I wrong lyrics', btn: btns[1] }, { img: 'img/3.jpg', id:2, songName: 'Sex,Drugs,Etc', audio : new Audio('audio/Sex-Drugs-Etc.mp3'), lyrics: 'Way Down We Go', }, { img: 'img/7.jpg', id:3, songName: 'Me Myself & I ', audio : new Audio('audio/Me-Myself-I.mp3'), lyrics: 'Me Myself & I lyrics', }, { img: 'img/4.jpg', id:4, songName: 'Blood In The Water', audio : new Audio('audio/Blood-In-The-Water.mp3'), lyrics: 'Blood In The Water lyrics', }, { img: 'img/3.jpg', id:5, songName: 'Eastside', audio : new Audio('audio/Eastside.mp3'), lyrics: 'Eastside lyrics', }, { img: 'img/6.jpg', id:6, songName: 'Everything Black ', audio : new Audio('audio/Everything-Black.mp3'), lyrics: 'Everything Black lyrics', }, ] const btnsLoop = () => { for (j = 0; j < btns.length; j++) { const musicObject = music[j]; const { img, id, songName, audio, lyrics } = musicObject; btns[j].addEventListener('click', () => { if(musicObject.audio.paused && musicObject.audio.currentTime > 0 && !musicObject.audio.ended) { musicObject.audio.play(); } else { musicObject.audio.pause(); } }) } } btnsLoop();
问题修复方案
1. 解决循环变量作用域问题
循环里的j没有用let声明,属于全局变量,导致所有点击事件绑定的都是最后一个musicObject。把j改成let j,让每次循环都创建独立的作用域。
2. 修正播放/暂停逻辑
原条件逻辑完全搞反了:应该是如果音频暂停,就播放;否则就暂停。不需要额外判断currentTime和ended,这些情况可以统一处理。
修复后的完整代码
const btns = Array.from(document.querySelectorAll('.song-details')); const music = [ { img: 'img/2.jpg', id: 1, songName: 'Am I Wrong', audio: new Audio('audio/Am-I-wrong.mp3'), lyrics: 'Am I wrong lyrics', btn: btns[1] }, { img: 'img/3.jpg', id: 2, songName: 'Sex,Drugs,Etc', audio: new Audio('audio/Sex-Drugs-Etc.mp3'), lyrics: 'Way Down We Go', }, { img: 'img/7.jpg', id: 3, songName: 'Me Myself & I ', audio: new Audio('audio/Me-Myself-I.mp3'), lyrics: 'Me Myself & I lyrics', }, { img: 'img/4.jpg', id: 4, songName: 'Blood In The Water', audio: new Audio('audio/Blood-In-The-Water.mp3'), lyrics: 'Blood In The Water lyrics', }, { img: 'img/3.jpg', id: 5, songName: 'Eastside', audio: new Audio('audio/Eastside.mp3'), lyrics: 'Eastside lyrics', }, { img: 'img/6.jpg', id: 6, songName: 'Everything Black ', audio: new Audio('audio/Everything-Black.mp3'), lyrics: 'Everything Black lyrics', }, ] const btnsLoop = () => { // 用let声明j,确保每次循环的作用域独立 for (let j = 0; j < btns.length; j++) { const musicObject = music[j]; btns[j].addEventListener('click', () => { // 简化逻辑:暂停就播放,播放就暂停 if (musicObject.audio.paused) { musicObject.audio.play(); } else { musicObject.audio.pause(); } }) } } btnsLoop();
额外优化建议
- 如果需要实现“点击其他歌曲时自动暂停当前播放的歌曲”,可以在播放新歌曲前遍历所有音频对象,暂停正在播放的。
- 可以给按钮添加播放/暂停状态的样式,让用户更直观看到当前状态。
内容的提问来源于stack exchange,提问作者Yasir Lasfar
相关产品推荐
相关产品推荐

