如何构建一个按钮来单击并播放/停止音频?

发布于 2025-01-09 12:46:50 字数 1148 浏览 0 评论 0原文

我想构建一个播放音频的图像按钮。 我的版本可以工作,但当我想在一个网站上多次使用它时,它只播放一个 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>

您知道该按钮仅在网站上播放其中之一的问题是什么吗?

i want to build a image button, that plays an audio.
My Version works but when I want to use it more than once on a site, it only play one mp3, not the other ones.

My Code:

<audio loop="false" src="audio_01.mp3"> </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>

and

<div id="BSong" onclick="playPause()" type="button">
<audio loop="false" src="audio_02.mp3"> </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>

So you have an idea what the problem is that the button only play one of them on the website?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无语# 2025-01-16 12:46:50

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

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

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

You are using the same variable names multiple times like aud, isPlayig, etc..

To solve this issue, you should declare only once the whole script and form the onclick="playPause()" send the id of the song you want to play.

Be aware if there is already some music which is playing.

天冷不及心凉 2025-01-16 12:46:50

很难说出当前的两个代码片段是如何相对彼此排列的,但是每次您想要添加另一个轨道时一遍又一遍地复制代码将是难以维护的。就目前情况而言,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="https://picsum.photos/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="https://picsum.photos/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="https://picsum.photos/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="https://picsum.photos/50/50" class="track-icon">
  </div>
</div>

关于您的代码的一些注释:

  • 不需要 isPlaying 变量,因为 audio 元素已经使用 audioElement.paused 跟踪其播放/暂停状态。如果您在外部状态下跟踪它,如果您的变量和音频元素的状态不同步,则会增加进一步的复杂性和错误空间。
  • 避免将
  • HTML 元素上的 onclick 通常是不好的做法。 HTML 应该是结构性的,而不是行为性的。同样,style="width: 40%;cursor:pointer" 应移动到外部样式表并应用于类。
  • .children[0]; 是选择轨道中音频元素的一种脆弱方法。如果您最终重新排列 div 中的元素,则此代码很容易被破坏。 document.querySelector("#BSong audio") 的重构更加精确和稳健,尽管使用类而不是 id 可以更轻松地实现动态性,因此您不必手动输入每个曲目。
  • CSS 类通常是短横线大小写,因此 hover_pic 将是 hover-pic

It's hard to tell how your two current code snippets are arranged with respect to each other, but duplicating the code over and over every time you want to add another track is going to be unmaintainable. As it stands, the variables for isPlaying and aud probably overwrite each other, depending on how they're laid out, even if they're in different scripts. Using const or let instead of var and use strict; at the top of your script can help detect these aliases.

You could add closures around each one to keep them distinct, but a better approach is to write a loop (which also acts as a scoping closure) and dynamically add the listener to each element. For example:

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="https://picsum.photos/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="https://picsum.photos/50/50" class="track-icon">
  </div>
</div>

Note that the above code lets multiple audio files play at once. If you want to stop all other audio elements when a new one is clicked and reset their time, you can do that with a loop or an extra variable that keeps track of the currently-playing track. For example:

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="https://picsum.photos/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="https://picsum.photos/50/50" class="track-icon">
  </div>
</div>

A few remarks on your code:

  • There's no need for isPlaying variables since audio elements already track their playing/paused state with audioElement.paused. If you track it in external state, you add further complication and room for bugs if your variable and the the audio element's state go out of sync.
  • Avoid putting a <script> in a <div>. <script> is usually a child of <body> or <head> (probably <body> in this case), after all of the HTML tags are closed.
  • onclick on an HTML element is generally poor practice. HTML should be structural, not behavioral. Similarly, style="width: 40%;cursor:pointer" should be moved to an external stylesheet and applied to a class.
  • .children[0]; is a brittle way to select the audio element in a track. If you wind up rearranging elements in the div, this code is liable to break. document.querySelector("#BSong audio") is more precise and robust to refactors, although using classes instead of ids enables easier dynamism so you don't have to type each track out by hand.
  • CSS classes are usually kebab-case, so hover_pic would be hover-pic.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文