Simple Javascript/CSS Jukebox Tutorial

- stop music
- crumblin_down.mp3
- dragula.mp3
- have_you_ever_seen_the_rain.mp3
- i_hate_myself_for_loving_you.mp3
- i_would_walk_500_miles.mp3
I call this a jukebox not only beceause I've come across a few other personal pages that call their music player one, but because its features are more limited than a modern music player. Like a jukebox, it has a selection of songs that the patron can select, and the user cannot change the volume or spot within a song. This makes our web jukebox much more simple because we dont need to alter the volume or time slider
I'm making this tutorial because in my own efforts to make my jukebox, I only found needlessly complex code, so I made my own from scratch! The length of this page may seem long, but the code really is simple! I just like to over explain things ^^
Note: my knowledge of javascript is very limited, I'm just throwing together bits I've learned during my efforts
HTML
Lets start with the HTML (then Javascript, lastly CSS). I will also skip the marquee for now.
< div class="jukebox" > < img src="https://solaria.neocities.org/smallgifs/cdspin.gif" > < ul > < li onclick="stopmusic()" >stop music< /li > < li value="0" onclick="playsong()">crumblin_down.mp3 < audio >< source src="https://media-upload.net/uploads/5S9FeDnNyrOE.mp3" type="audio/mp3" >< /audio > < /li> < li value="1" onclick="playsong()">dragula.mp3 < audio >< source src="https://media-upload.net/uploads/e6gThUtmqE2z.mp3" type="audio/mp3" >< /audio > < /li > < li value="2" onclick="playsong()">have_you_ever_seen_the_rain.mp3 < audio >< source src="https://media-upload.net/uploads/gTKMVftE8oCu.mp3" type="audio/mp3" >< /audio > < /li > < li value="3" onclick="playsong()">i_hate_myself_for_loving_you.mp3 < audio >< source src="https://media-upload.net/uploads/TRNy3ljbSKXa.mp3" type="audio/mp3" >< /audio > < /li > < li value="4" onclick="playsong()">i_would_walk_500_miles.mp3 < audio >< source src="https://media-upload.net/uploads/KGSmbhNQCsfF.mp3" type="audio/mp3" >< /audio > < /li > < /ul > < /div >
This is the full HTML
- First we make a div container for the jukebox, this holds the songs, the image (and eventually the marquee)
- Next is simply the image I used to represent the jukebox. You could also give the jukebox div a background image if you wished
- I made a list for my songs, but you can oraganize them however you like
- I put the stop music function in the list, but you can put it wherever you want
Lets look closer at each list item:
< li value="0" onclick="playsong()">crumblin_down.mp3 < audio >< source src="https://media-upload.net/uploads/5S9FeDnNyrOE.mp3" type="audio/mp3" >< /audio > < /li >
- value="0" - I gave each list item a value, with the first one starting at zero, the second song will have a value of one - this is used to identify the list item in the javascript
- it is important that these are numbered like this for the right song to play
- I chose the value attribute for them, but I imagine you could also do id or class with the numbers as well
- onclick="playsong()" - the javascript function that happens when the user clicks the list item
- the actual javascript code that happens will be contained else where
- each list item will have the same function
- crumblin_down.mp3 - this is the text we want to show up for the user to click on - the song name (this isnt actually a file, i just named it like one for fun)
< audio >< source src="https://media-upload.net/uploads/5S9FeDnNyrOE.mp3" type="audio/mp3" >< /audio >
- the code for embeding a music file into a webpage
- note how the source is a tag between the audio tags, rather than just an attribute within the start audio tag
- src="" - the file name goes inside the source attribute (which is in the source tag)
- if these are your own songs you can upload the files directly to neocities
- if it is copywrited material like mine, you can upload them to a third party site you can hotlink to, so you dont violate neocities terms of service (i used media-upload.net)
- you dont even need type="audio/mp3" its just nice to put
- we would use
< audio controls >
if we wanted to allow the user to adjust the volume and position of each song, but each browser styles the controls differently, and you need a lot of extra javascript to style them your own way. since i want a basic jukebox i omit the controls
JavaScript
The following code is in the head of the document (but not in the style section), you could also put it in the body of the document
< script >
function playsong() {
var y = document.getElementsByTagName('audio');
for(var j=0; j<y.length; j++) {
y[j].pause();}
var songvalue = event.target.value;
document.getElementsByTagName('audio')[songvalue].currentTime = 0;
document.getElementsByTagName('audio')[songvalue].play();}
function stopmusic() {
var y = document.getElementsByTagName('audio');
for(var j=0; j<y.length; j++) {
y[j].pause();}
< /script >
this is the full javascript
- I have two functions: playsong() {} and stopmusic() {}
- function is declared before them to let javascript know that they are functions
First Function
function playsong() {
var y = document.getElementsByTagName('audio');
for(var j=0; j<y.length; j++) {
y[j].pause();}
var songvalue = event.target.value;
document.getElementsByTagName('audio')[songvalue].currentTime = 0;
document.getElementsByTagName('audio')[songvalue].play();
var y = document.getElementsByTagName('audio');
for(var j=0; j<y.length; j++) {
y[j].pause();}
- this first section in the playsong() function is used to stop any other songs the user clicked on, so there is no audio overlap
- the first line makes a variable
y
and defines it as the audio element - the next line basically makes it so that every audio element is selected, rather than just the first one (see my javascript tutorial for more details)
- the third line pauses the selected audio elements
pause()
is a predefined javascript function that javascript already knows how to use
var songvalue = event.target.value; document.getElementsByTagName('audio')[songvalue].currentTime = 0; document.getElementsByTagName('audio')[songvalue].play();
- the second section plays the song!
- the first line created another variable: songvalue
- this is where the value="" i gave each list element comes in
- event.target identifies the clicked list item
- .value identifies the value we gave the clicked item
- basically this variable is the same number as the value of the clicked list element
document.getElementsByTagName('audio')[songvalue]
identifies the audio elements - the brackets[]
identifies which audio element, since we have multiple- in these brackets goes a number
- document.getElementsByTagName('audio')[0] - the first audio element
- document.getElementsByTagName('audio')[1] - the second audio element
- document.getElementsByTagName('audio')[2] - the third audio element
- since we need a [0] to get the first song, we had to give the first list element holding audio, a value of 0
- the variable songvalue picks the value for each list item, which we made correspond to the audio element it contains, thus when placed in the brackets
document.getElementsByTagName('audio')[songvalue]
it chooses the corresponding audio element
- in these brackets goes a number
- .currentTime = 0; - makes the song selected start at the beginning
- useful if a user listened to a song partly through, clicked on a another song, and then clicked back onto the first one
- this prevents the first song from resuming where it was left off
- .play() - a predefined javascript function that plays an audio or video element
Second Function
function stopmusic() {
var y = document.getElementsByTagName('audio');
for(var j=0; j<y.length; j++) {
y[j].pause();}
- the second function stopmusic() pauses all audio elements
- it is actually the same as the first part of function playsong() - it simply doesn't include code to play a song after they are all paused
CSS
The css is pretty simple, infact if you want the song menu to be visable all the time, rather than on hover, you can style everything however you like. This CSS will show you how to make the list menu appear when the user hovers over the jukebox div
.jukebox { position: relative; width: 100px;} .jukebox ul { display: none; list-style: none; background: purple; position: absolute; top: 0px; left: 100px;} .jukebox:hover ul { display: inline-block;} jukebox li:hover { background: pink;}
This is a basic formatting of the css, with most of the personal preference styling removed for clairity. Still there are things like the width, and backgrounds that are up to you to decide
- first is the class .jukebox used to style the div element
position: relative;
is the most important part - this allows us to position the song list in relationship to the jukebox div- width can be anything you want, though you probably dont want it 100%
- .jukebox ul - this styles the whole list within the jukebox div
position: absolute;
- the needed counterpart to position: relative in order for the list to be positioned relative to the jukebox div- top: 0px and left: 100px determine how far away the list is from the jukebox div
- the top left corner of the list is at the same height as the top left corner of the jukebox div, and 100px to the right
- display: none - this makes it so that the song list is hidden
- list-style: none - this removes the bullet points from the list items
.jukebox:hover ul { display: inline-block;}
- when the user hovers over the jukebox div, the whole list will show up- i use inline-block beacuse I dont need the list element to be any wider than the longest song title
- you can style the .jukebox li (list item) any way you like - I like to make the background change color on hover
Marquee
Completeley optional, but this adds scrolling text that lets the viewer know which song is playing, or if any music is playing at all
< marquee > < p id="marq" >select a song!< /p > < /marquee >
This is the HTML for the marquee. it holds a paragraph element that has an id (you can name it anything as long as it has one for the javascript)
< li value="0" title="Crumblin Down - John Mellencamp" onclick="playsong()">crumblin_down.mp3 < audio >< source src="https://media-upload.net/uploads/5S9FeDnNyrOE.mp3" type="audio/mp3" >< /audio > < /li >
Here is the list item again. I used title="" to store the text i want the marquee to display (song title and artist). you dont have to do this if what you want to display is the same as the text inside the list element
function playsong() { document.getElementById('marq').innerHTML = event.target.title;} function stopmusic() { document.getElementById('marq').innerHTML = 'no music is playing';}
Here are the two javascript functions we made earlier, each with an extra line for the marquee
document.getElementById('marq').innerHTML
this selects the text inside of the element we gave the #marq id- event.target.title - this identifies the title="" attribute of the clicked list element, thus making the marquee display the title text of the clicked song
- if you want to make the marque display the same text as the list element, use event.target.innerHTML
- the stopmusic() marquee text does not depend on song, so we can use plain text for the message
there is one more thing to add
var y = document.getElementsByTagName('audio');
for(var j=0; j<y.length; j++) {
y[j].onended = function() {
document.getElementById('marq').innerHTML = 'select a song!';};}
without this bit of javascript, the marquee would continue to display a songs name after the song finished on its own (the marquee so far only changes when a different song is chosen, or the stop button is clicked)
- this code does not go in either function, rather its sets up an additional unnamed function
- it is important to note that this function is not an onclick function, infact it doesnt require any user input
- instead it makes a function for what happens when an audio element has reached the end of its content
- first the audio elements are identified similarly to how we pause the music
- but instead of pausing y[j] (the audio elements) we make a function for what happens when they end (
.onended
) - the function is the same as the other lines that alter the inner HTML of the #marq element, except I repeated the text that displays before a song is chosen, which lets the user know the song has ended and they can select another song
- note: this function may not work if it is in the head of the html document. I ended up putting mine in a seperate script tag in my .jukebox div after the songs
Thats it! Have fun ^^