Reputation: 1636
I have 10 audio players with simple html audio tags on a html5 page. No jquery, no special audio js plugins, etc...
Does anyone has a simple script in js to pause all other players when the current player is playing ?
I don't want to use js plugins because i want to keep a simple audio html code.
Upvotes: 38
Views: 34092
Reputation: 15056
Instead of looping over all audio/video tags on a page and pausing them, you can store a reference to the currently playing element, and have only that one pause when playing another.
document.addEventListener("play", function(evt) {
if(this.$MediaActive && this.$MediaActive !== evt.target) {
this.$MediaActive.pause();
}
this.$MediaActive = evt.target;
}, true);
Using the this
keyword allows the $MediaActive
variable to be scoped to the listener object itself. This works because the listener is instantiated only once, and whenever the play
event is triggered, $MediaActive
will reflect the previous element it was set to.
If external access is required, one may replace this
with any object they require. For example, using window
will store the variable in the global scope.
Upvotes: 16
Reputation: 35
You can even try this solution, if you don't want to loop through
var previousAudio;
document.addEventListener('play', function(e){
if(previousAudio && previousAudio != e.target){
previousAudio.pause();
}
previousAudio = e.target;
}, true);
Upvotes: 0
Reputation: 11
Best solution rewritten regarding ECMA 2022:
document.addEventListener('play', (event) => {
const audios = [...document.getElementsByTagName('audio')];
audios.forEach((audio) => audio !== event.target && audio.pause());
}, true);
Upvotes: 1
Reputation: 1
I made a player at the bottom and changed the src every time the user clicks on play this is just one way of doing it
HTML
<audio src="tracks/track1.mp3" type="audio/mp3" class='audios'></audio>
<i class='fas fa-play'></i>
<i class='far fa-pause-circle'></i>
<i class='fas fa-stop'></i>
<audio src="tracks/track2.mp3" type="audio/mp3" class='audios'></audio>
<i class='fas fa-play'></i>
<i class='far fa-pause-circle'></i>
<i class='fas fa-stop'></i>
<audio src="tracks/track3.mp3" type="audio/mp3" class='audios'></audio>
<i class='fas fa-play'></i>
<i class='far fa-pause-circle'></i>
<i class='fas fa-stop'></i>
<audio class='main-audio' controls>
<source src="#" type="audio/mp3">
</audio>
JavaScript
const audios_with_src = document.querySelectorAll('.audios')
const play = document.querySelectorAll('.fa-play')
const pause = document.querySelectorAll('.fa-pause-circle')
const stop = document.querySelectorAll('.fa-stop')
const main_player = document.querySelector('.main-audio')
for(let i =0; i < audios_with_src.length; i++) {
play[i].addEventListener('click', (e) => {
main_player.src = audios_with_src[i].src;
main_player.play()
})
pause[i].addEventListener('click', () => {
main_player.pause()
})
stop[i].addEventListener('click', () => {
main_player.pause()
main_player.currentTime = 0; // there is no stop() function so had to do this
})
}
Upvotes: 0
Reputation: 201
I don't know if it is because of Chrome updates, but the previous answers did not work for me. I modified a bit of the code here and came up with this:
document.addEventListener("play", function(evt)
{
if(window.$_currentlyPlaying && window.$_currentlyPlaying != evt.target)
{
window.$_currentlyPlaying.pause();
}
window.$_currentlyPlaying = evt.target;
}, true);
I don't know why, but the widow.addEventListener
was not working for me, but I liked the idea of having the currentPlaying
variable stored in the window
element instead of having to create it outside of the listener prior to using it.
Upvotes: 1
Reputation: 3775
$("audio").on("play", function() {
var id = $(this).attr('id');
$("audio").not(this).each(function(index, audio) {
audio.pause();
});
});
$("video").on("play", function() {
var id = $(this).attr('id');
$("video").not(this).each(function(index, video) {
video.pause();
});
});
Upvotes: 3
Reputation: 2027
Mixing both previous answers that didn't work, i've used that. I just added && window.$_currentlyPlaying != evt.target
and all is working.
Also i've created a gist with this and other goodies for audio tags. javascript-audio-tags
window.addEventListener("play", function(evt)
{
if(window.$_currentlyPlaying && window.$_currentlyPlaying != evt.target)
{
window.$_currentlyPlaying.pause();
}
window.$_currentlyPlaying = evt.target;
}, true);
Upvotes: 6
Reputation: 14154
you can use event delegation. Simply listen to the play event in the capturing phase and then pause all video file, but not the target one:
document.addEventListener('play', function(e){
var audios = document.getElementsByTagName('audio');
for(var i = 0, len = audios.length; i < len;i++){
if(audios[i] != e.target){
audios[i].pause();
}
}
}, true);
Upvotes: 122