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

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();
});

问题根源

  1. 两套播放逻辑冲突:同时使用了两种播放方式——通过playAudio()创建新Audio对象播放,以及通过页面的#audioPlayer元素播放。但ended事件只绑定在#audioPlayer上,点击列表项调用playAudio()时,实际播放的是新创建的Audio实例,和#audioPlayer无关,自然触发不了它的ended事件。
  2. 变量作用域错误: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:35:23