网页多HTML5 Audio播放问题求助:ID改Class后无法播放
解决多个HTML5 Audio元素无法播放的问题
看起来你已经意识到ID唯一性的问题,但改成class后踩了几个常见的DOM操作坑,咱们一步步来修复:
首先看你代码里的几个关键错误:
- DOM方法名称错误:没有
getElementByClass这个方法,正确获取多个class元素的方法是document.getElementsByClassName(),它返回的是一个HTMLCollection(元素集合),不是单个元素,直接像之前操作单个元素那样用会报错。 - HTML属性写法错误:一个标签不能有多个
class属性,比如<a class="btn" class="nyan-btn"></a>是无效的,应该合并成<a class="btn nyan-btn"></a>。 - 事件绑定逻辑问题:原来的代码只给单个按钮绑定了事件,但现在有多个音频和按钮,需要给每一组按钮和对应的音频分别绑定事件。
修正后的完整代码:
第一步:修正HTML结构
<!-- 第一组音频+按钮 --> <audio class="nyan" src="https://elysian.dijestdesigns.com/wp-content/uploads/2020/02/Jessica_Roberts_Afrikaans_Corporate_SouthAfrican-sassa.mp3" preload="metadata" type="audio/mpeg"> Your browser does not support the audio element. </audio> <a class="btn nyan-btn"></a> <!-- 第二组音频+按钮 --> <audio class="nyan" src="https://elysian.dijestdesigns.com/wp-content/uploads/2020/02/Jessica_Roberts_Afrikaans_Corporate_SouthAfrican-sassa.mp3" preload="metadata" type="audio/mpeg"> Your browser does not support the audio element. </audio> <a class="btn nyan-btn"></a>
第二步:修正JavaScript逻辑
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js" type="text/javascript"></script> <script> // 获取所有音频和按钮元素(注意方法名是getElementsByClassName) var nyanElements = document.getElementsByClassName("nyan"); var nyanBtnElements = document.getElementsByClassName("nyan-btn"); function playPause(song) { if (song.paused && song.currentTime >= 0 && !song.ended) { song.play(); } else { song.pause(); } } function reset(btn, song) { if (btn.classList.contains("playing")) { btn.classList.toggle("playing"); } song.pause(); song.currentTime = 0; } function progress(btn, song) { // 加个判断:如果音频暂停或已结束,就停止递归,避免内存泄漏 if (song.paused || song.ended) return; setTimeout(function () { // 先判断duration是否加载完成(避免NaN错误) if (isNaN(song.duration)) { progress(btn, song); return; } var end = song.duration; var current = song.currentTime; var percent = current / (end / 100); // 检查是否播放结束 if (current >= end) { reset(btn, song); return; } // 更新按钮阴影 btn.style.boxShadow = "inset " + btn.offsetWidth * (percent / 100) + "px 0px 0px 0px rgba(0,0,0,0)"; // 继续递归调用 progress(btn, song); }, 1000); } // 循环给每一组按钮和音频绑定事件 for (let i = 0; i < nyanBtnElements.length; i++) { const btn = nyanBtnElements[i]; const song = nyanElements[i]; btn.addEventListener("click", function () { btn.classList.toggle("playing"); playPause(song); // 只有播放时才启动进度更新 if (!song.paused) { progress(btn, song); } }); } </script>
关键修正点解释:
- 修正DOM获取方法:用
getElementsByClassName获取所有对应class的元素,得到集合后通过索引访问单个元素。 - 合并HTML的class属性:把多个class属性合并到一个
class里,符合HTML规范。 - 循环绑定事件:通过
for循环遍历每一组按钮和音频,确保每个按钮只控制对应的那个音频。 - 优化progress函数:增加了
duration是否加载完成的判断(避免音频元数据未加载时出现NaN错误),同时在音频暂停或结束时停止递归,防止不必要的性能消耗和内存泄漏。
这样修改后,每个按钮就能独立控制对应的音频播放/暂停,并且进度条也能正常工作啦~
内容的提问来源于stack exchange,提问作者Jessica
相关产品推荐
相关产品推荐

