I'm currently working on a music player using the inbuilt audio API in javascript. It looks like this:
I have a playlist function which changes the song every time I press the different tabs where the songs are listed. The code looks like this.
$('#song1').click(function() {
audio.pause();
audio.currentTime = 0;
audio.src = "../sounds/1.mp3";
audio.play();
});
$('#song2').click(function() {
audio.pause();
audio.currentTime = 0;
audio.src = "../sounds/2.mp3";
audio.play();
});
$('#song3').click(function() {
audio.pause();
audio.currentTime = 0;
audio.src = "../sounds/3.mp3";
audio.play();
});
$('#song4').click(function() {
audio.pause();
audio.currentTime = 0;
audio.src = "../sounds/4.mp3";
audio.play();
});
$('#song5').click(function() {
audio.pause();
audio.currentTime = 0;
audio.src = "../sounds/5.mp3";
audio.play();
});
$('#song6').click(function() {
audio.pause();
audio.currentTime = 0;
audio.src = "../sounds/6.mp3";
audio.play();
});
How can I can get this into one function instead of six? I also need to be able to choose how many songs there are if I add more tabs in the playlist. Thank you
The technique you're trying to employ here is called 'Don't Repeat Yourself', or 'DRY'.
The simplest way to do it in this case is to make the HTML structure common to all the elements, but use class
attributes to group them and data
attributes to hold custom meta data. Then you can use a single event handler on them all, something like this:
<button class="song" data-src="../sounds/1.mp3">Song 1</button>
<button class="song" data-src="../sounds/2.mp3">Song 2</button>
$('.song').click(function() {
audio.pause();
audio.currentTime = 0;
audio.src = $(this).data('src');
audio.play();
});
This technique has several benefits, including cleaner and simpler HTML and JS code, and a better separation of concerns; that is to say, if you want to add another file to be played you simply add another HTML element with the correct data
attribute and you're done without having to touch the JS code.
Also note that you may need to call audio.load()
before audio.play()
if the content is not yet cached.