質問するログイン新規登録

Q&A

解決済

1回答

259閲覧

1つだけ起動するオーディオの再生・停止ボタンの実装方法

inbloom0710

総合スコア3

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2024/04/28 12:16

0

0

実現したいこと

オーディオの再生ボタンが10個あり、各ボタンはクリックで再生・停止できるトグルボタンになっています。
いずれかのオーディオの再生中に他の再生ボタンをクリックすると、再生中の楽曲が停止し、クリックしたボタンの音源が再生されます。

その際、先に再生していたオーディオのボタンは再生前の状態(PLAY▶)に戻り、新たにクリックしたボタンが再生中の外観(PAUSE)に変わります。
外観の変化はCSSのis_activeクラスの付け替えで行っています。

発生している問題・分からないこと

あるオーディオの再生中に、他の音源の再生ボタンを押した時の挙動が上手くいきません。
オーディオの切り替えはできていますが、CSSのクラスの付け替えが上手くできていない状態です。

恐れ入りますが、分かる方がいましたら知恵をお借りできますと幸いです。
よろしくお願いいたします。

該当のソースコード

JavaScript

1//視聴ボタンのオーディオ再生 2document.addEventListener('DOMContentLoaded', () => { 3 4 const audioPlayers = document.querySelectorAll('.player'); 5 6 audioPlayers.forEach((audioPlayer) => { 7 // .audio-player を基点として audio 要素を取得 8 const audio = audioPlayer.querySelector('audio'); 9 // ボリュームを調整(必要に応じて。初期値は 1.0) 10 audio.volume = .1; 11 // .audio-player を基点としてボタンと表示テキストを取得 12 const toggleBtn = audioPlayer.querySelector('.btn_play'); 13 const BtnText = audioPlayer.querySelector('.btntext'); 14 15 // .audio-player を基点としてSVG要素を取得 16 const playIcon = audioPlayer.querySelector('.play'); 17 const stopIcon = audioPlayer.querySelector('.stop'); 18 19 // ボタンのクリックイベントのリスナー 20 toggleBtn.addEventListener('click', togglePlayPause, false); 21 // audio 要素の再生終了時に発行される ended イベントのリスナー 22 audio.addEventListener('ended', audioEnded, false); 23 24 25 // ドキュメントの play イベント 26 document.addEventListener('play', (e) => { 27 // 全ての audio 要素を取得 28 const audios = document.querySelectorAll('audio'); 29 // それぞれの audio 要素で以下を実行 30 audios.forEach((audio) => { 31 // play イベントが発生した要素が自身でなければ停止 32 if(audio !== e.target) { 33 audio.pause(); 34 audio.currentTime = 0; //先頭に戻す場合(もし必要であれば) 35 } 36 }); 37 }, true); // addEventListener()の第3引数(useCapture)を true に 38 39 40 // トグルボタンのリスナー 41 function togglePlayPause() { 42 // 一時停止中かどうかで処理を分岐 43 if (audio.paused) { 44 // 一時停止中の場合は再生 45 audio.play(); 46 toggleBtn.classList.add("playing"); 47 48 playIcon.classList.remove("is_active"); 49 stopIcon.classList.add("is_active"); 50 51 BtnText.textContent = 'STOP'; 52 } else { 53 // 一時停止中でない(再生中)の場合は一時停止 54 audio.pause(); 55 audio.currentTime = 0; 56 toggleBtn.classList.remove("playing"); 57 58 stopIcon.classList.remove("is_active"); 59 playIcon.classList.add("is_active"); 60 61 BtnText.textContent = 'PLAY'; 62 } 63 } 64 65 // 再生終了時にはトグルボタンのラベルを Play に変更 66 function audioEnded() { 67 BtnText.textContent = 'PLAY'; 68 toggleBtn.classList.remove("playing"); 69 stopIcon.classList.remove("is_active"); 70 playIcon.classList.add("is_active"); 71 } 72 73 }); 74}, false);

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

playイベントと同じように、トグルイベントにも if(audio !== e.target) のような分岐を設けるべきという考えには至っていますが、具体的な記述方法にたどり着けていない状況です。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

guest

回答1

0

自己解決

ended イベントだけでなくpauseイベントのリスナーを追加する事で解決できました。

// 再生中に他のボタンを押した時に発生する pause イベントのリスナー
audio.addEventListener('pause', audioEnded, false);

を追記しました。

投稿2024/04/28 15:53

inbloom0710

総合スコア3

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.29%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問