HTML5音频播放列表ended事件未触发,无法自动播放下一曲
音频播放列表自动播放下一曲失效问题
我参考教程定制音频播放列表,遇到的问题是:音频播放结束后,ended事件监听器未检测到事件,无法自动播放下一曲。我猜测原因是音频通过HTML的onclick点击触发播放,而非加载到audioPlayer元素中。
HTML代码
<body> <audio controls id="audioPlayer" autoplay="false"> Sorry, your browser doesn't support html5! </audio> <ul id="playlist"> <li class="current-song" > <a class="audio song" src="test.wav" onclick="playAudio('test.wav')"> test </a></li> <li><a class="audio song" src="algebrasuicide_fathersbythedoor.wav" onclick= "playAudio('algebrasuicide_fathersbythedoor.wav')">algebra suicide <i>father by the door</i> </a></li> <li><a class="audio song" src="algebrasuicide_inbedwithboys.wav" onclick= "playAudio('algebrasuicide_inbedwithboys.wav')"> algebra suicide <i>in bed with boys</i> </a></li> <li><a class="audio song" src="aprilmagazine_parade.wav" onclick="playAudio('aprilmagazine_parade.wav')"> april magazine <i>parade</i> </a></li> <ul> <button id="button">PAUSE</button> <script src="https://code.jquery.com/jquery-2.2.0.js"></script> <script src="js/script.js"></script> <script> // loads the audio player audioPlayer(); </script> </body>
JS代码
let audio; function stopAudio() { // If audio in not undefined and if is playing, pause it if (audio && !audio.paused) { audio.pause(); audio.currentTime = 0; // Rewind track to beginning (is you need this) } } function playAudio(src) { stopAudio(); // Pause any currently playing audio = new Audio(); // Save a reference audio.src = src; audio.play(); } function pauseAudio(){ audio.pause(); } var button = document.getElementById("button"); button.addEventListener("click", function(){ if(audio.paused){ audio.play(); button.innerHTML = "Pause"; } else { pauseAudio(); button.innerHTML = "Play"; } }); function audioPlayer(){ var currentSong = 0; $("#audioPlayer")[0].src = $("#playlist li a")[0]; $("#playlist li a").click(function(e){ e.preventDefault(); $("#audioPlayer")[0].src = this; $("#playlist li").removeClass("current-song"); currentSong = $(this).parent().index(); $(this).parent().addClass("current-song"); }); } $("#audioPlayer")[0].addEventListener("ended", function(){ alert("hi"); currentSong++; if(currentSong == $("#playlist li a").length) currentSong = 0; $("#playlist li").removeClass("current-song"); $("#playlist li:eq("+currentSong+")").addClass("current-song"); $("#audioPlayer")[0].src = $("#playlist li a")[currentSong].href; $("#audioPlayer")[0].play(); }); $(document).ready(function() { audioPlayer(); });
问题根源
- 两套播放逻辑冲突:同时使用了两种播放方式——通过
playAudio()创建新Audio对象播放,以及通过页面的#audioPlayer元素播放。但ended事件只绑定在#audioPlayer上,点击列表项调用playAudio()时,实际播放的是新创建的Audio实例,和#audioPlayer无关,自然触发不了它的ended事件。 - 变量作用域错误:
currentSong定义在audioPlayer()函数内部,外部的ended事件回调无法访问该变量,会导致报错。
修复方案
1. 移除HTML中的onclick属性
删掉所有列表项里的onclick="playAudio('xxx.wav')",统一用audioPlayer的逻辑控制播放。修改后的列表项示例:
<li class="current-song"> <a class="audio song" src="test.wav">test</a> </li>
2. 清理冗余函数
删除stopAudio()、playAudio()、pauseAudio()函数,以及按钮事件中针对audio变量的逻辑,统一用#audioPlayer元素控制播放。
3. 修正变量作用域
把currentSong提升到全局作用域,让ended事件回调能访问到它。
4. 统一按钮控制逻辑
修改按钮事件为控制#audioPlayer:
var button = document.getElementById("button"); var audioPlayer = $("#audioPlayer")[0]; button.addEventListener("click", function(){ if(audioPlayer.paused){ audioPlayer.play(); button.innerHTML = "Pause"; } else { audioPlayer.pause(); button.innerHTML = "Play"; } });
5. 修正ended事件的音频地址
列表项的a标签用src存地址,所以ended事件里要取src而非href:
audioPlayer.src = $("#playlist li a")[currentSong].getAttribute("src");
最终完整代码
HTML代码
<body> <audio controls id="audioPlayer" autoplay="false"> Sorry, your browser doesn't support html5! </audio> <ul id="playlist"> <li class="current-song"> <a class="audio song" src="test.wav">test</a> </li> <li> <a class="audio song" src="algebrasuicide_fathersbythedoor.wav">algebra suicide <i>father by the door</i></a> </li> <li> <a class="audio song" src="algebrasuicide_inbedwithboys.wav">algebra suicide <i>in bed with boys</i></a> </li> <li> <a class="audio song" src="aprilmagazine_parade.wav">april magazine <i>parade</i></a> </li> </ul> <button id="button">PAUSE</button> <script src="https://code.jquery.com/jquery-2.2.0.js"></script> <script> var currentSong = 0; var audioPlayer = $("#audioPlayer")[0]; function audioPlayerInit(){ audioPlayer.src = $("#playlist li a")[0].getAttribute("src"); $("#playlist li a").click(function(e){ e.preventDefault(); audioPlayer.src = this.getAttribute("src"); $("#playlist li").removeClass("current-song"); currentSong = $(this).parent().index(); $(this).parent().addClass("current-song"); audioPlayer.play(); }); } audioPlayer.addEventListener("ended", function(){ currentSong++; if(currentSong == $("#playlist li a").length){ currentSong = 0; } $("#playlist li").removeClass("current-song"); $("#playlist li:eq("+currentSong+")").addClass("current-song"); audioPlayer.src = $("#playlist li a")[currentSong].getAttribute("src"); audioPlayer.play(); }); var button = document.getElementById("button"); button.addEventListener("click", function(){ if(audioPlayer.paused){ audioPlayer.play(); button.innerHTML = "Pause"; } else { audioPlayer.pause(); button.innerHTML = "Play"; } }); $(document).ready(function() { audioPlayerInit(); }); </script> </body>
内容的提问来源于stack exchange,提问作者fausdv
相关产品推荐
相关产品推荐

