如何建立一个按钮来点击和播放/停止音频



我想建立一个图像按钮,播放音频。我的版本是有效的,但当我想在网站上多次使用它时,它只播放一个mp3,而不播放其他mp3。

我的代码:

<audio loop="false" src="audio_01.mp3">&nbsp;</audio>
<p><img alt="" class="hover_pic" src="image.png" style="width: 40%;cursor:pointer" /></p>
<script>
var aud = document.getElementById("ASong").children[0];
var isPlaying = false;
aud.pause();
function playPause() {
if (isPlaying) {
aud.pause();
} else {
aud.play();
}
isPlaying = !isPlaying;
}
</script></div>

<div id="BSong" onclick="playPause()" type="button">
<audio loop="false" src="audio_02.mp3">&nbsp;</audio>
<p><img alt="" class="hover_pic" src="image.png" style="width: 40%;cursor:pointer" /></p>
<script>
var aud = document.getElementById("BSong").children[0];
var isPlaying = false;
aud.pause();
function playPause() {
if (isPlaying) {
aud.pause();
} else {
aud.play();
}
isPlaying = !isPlaying;
}
</script></div>

所以你知道按钮在网站上只播放其中一个按钮有什么问题吗?

您多次使用相同的变量名,如aud、isPlayig等。

为了解决这个问题,您应该只声明整个脚本一次,并形成onclick="playPause(("发送您要播放的歌曲的id。

注意是否已经有一些音乐在播放。

很难判断您的两个当前代码片段是如何相互排列的,但每次您想添加另一个音轨时都会重复代码,这是不可维护的。目前,isPlayingaud的变量可能会相互覆盖,这取决于它们的布局方式,即使它们位于不同的脚本中。在脚本顶部使用constlet而不是varuse strict;可以帮助检测这些别名。

您可以在每个元素周围添加闭包,以保持它们的不同,但更好的方法是编写一个循环(它也充当作用域闭包(,并将侦听器动态添加到每个元素。例如:

const trackEls = [...document.querySelectorAll(".track")];
for (const trackEl of trackEls) {
const audioEl = trackEl.querySelector("audio");
trackEl.addEventListener("click", () => {
audioEl.paused ? audioEl.play() : audioEl.pause();
});
}
<div class="tracks">
<div type="button" class="track">
<audio src="https://upload.wikimedia.org/wikipedia/commons/d/d8/Bourne_woods_2020-11-18_0732.mp3"></audio>
<img alt="play track icon" src="http://placekitten.com/50/50" class="track-icon">
</div>
<div type="button" class="track">
<audio src="https://upload.wikimedia.org/wikipedia/commons/e/ea/Rapid-Acoustic-Survey-for-Biodiversity-Appraisal-pone.0004065.s017.ogg"></audio>
<img alt="play track icon" src="http://placekitten.com/50/50" class="track-icon">
</div>
</div>

请注意,上面的代码允许同时播放多个音频文件。如果你想在点击新的音频元素并重置它们的时间时停止所有其他音频元素,你可以通过一个循环或一个额外的变量来跟踪当前播放的曲目。例如:

const trackEls = [...document.querySelectorAll(".track")];
let currentTrack;
for (const trackEl of trackEls) {
const audioEl = trackEl.querySelector("audio");
trackEl.addEventListener("click", () => {
if (audioEl !== currentTrack) {
if (currentTrack) {
currentTrack.pause();
currentTrack.currentTime = 0;
}
currentTrack = audioEl;
}
audioEl.paused ? audioEl.play() : audioEl.pause();
});  
}
<div class="tracks">
<div type="button" class="track">
<audio src="https://upload.wikimedia.org/wikipedia/commons/d/d8/Bourne_woods_2020-11-18_0732.mp3"></audio>
<img alt="play track icon" src="http://placekitten.com/50/50" class="track-icon">
</div>
<div type="button" class="track">
<audio src="https://upload.wikimedia.org/wikipedia/commons/e/ea/Rapid-Acoustic-Survey-for-Biodiversity-Appraisal-pone.0004065.s017.ogg"></audio>
<img alt="play track icon" src="http://placekitten.com/50/50" class="track-icon">
</div>
</div>

关于您的代码的几点备注:

  • 不需要isPlaying变量,因为audio元素已经用audioElement.paused跟踪它们的播放/暂停状态。若您在外部状态下跟踪它,若您的变量和音频元素的状态不同步,则会增加更多的复杂性和错误空间
  • 避免在<div>中放入<script>。在关闭所有HTML标记之后,<script>通常是<body><head>(在这种情况下可能是<body>(的子级
  • HTML元素上的onclick通常是不好的做法。HTML应该是结构化的,而不是行为性的。类似地,style="width: 40%;cursor:pointer"应该被移动到一个外部样式表并应用到一个类
  • CCD_ 18是选择音轨中的音频元素的一种脆弱方式。如果您最终重新排列div中的元素,则此代码可能会中断。document.querySelector("#BSong audio")对于重构来说更精确、更健壮,尽管使用类而不是id可以实现更容易的动态性,因此不必手动键入每个轨迹
  • CSS类通常是kebab的情况,所以hover_pic应该是hover-pic

最新更新