I have a Music Player with Custom Buttons, & underneath is a Playlist with some songs. I thought I was close at one point, but in the process of trying to figure this out, I lost that version of code, so I may be missing a lot of seemingly obvious pieces of code (mostly JavaScript, but I am sure some of HTML also)
WHAT I NEED:
Loading the page by default, the play button is shown (located in HTML as button class 'button--play') & the text (icon) on it is (wrapped in <button>
, <i class="ph-play">
...)
SO WHEN I CLICK on, for instance, Dangerous Woman, the 1st song, I need it to begin playing, as well as the text on the button--play to change from 'ph-play' to 'ph-pause' AS WELL AS that button's Class to change from 'button--play' to 'button--pause'.
With that knowledge, assuming a song is playing, I should also be able to click on the pause button, & the song pause.
Like I mentioned, I am missing A LOT because I was much closer to solving this at one point, so this is very irritating now... JS is from ChatGPT...
// Assuming each song element has a class name 'song' and data attribute 'data-src' containing the audio source
// Get all song elements
const songs = document.querySelectorAll('.Tracks-Title');
// Loop through each song element
songs.forEach(song => {
// Add click event listener
song.addEventListener('click', function() {
// Get the audio source from the data-src attribute
const audioSource = this.getAttribute('data-src');
// Change the audio source
audio.src = audioSource;
// Play the new song
audio.play();
});
});
/**** Controls ****/
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap");
*,
*:before,
*:after {
box-sizing: border-box;
}
.controls-box {
line-height: 1.5;
/* min-height: 100vh;*/
font-family: "Inter", sans-serif;
display: flex;
flex-direction: column;
gap: 2rem;
align-items: center;
justify-content: center;
color: #b4bcd0;
}
button,
input,
select,
textarea {
font: inherit;
color: inherit;
}
a {
color: inherit;
}
:root :has(.theme-toggle input:checked) {
--color-text-primary: rgb(180, 188, 208);
--color-text-secondary: rgb(255, 255, 255);
--color-background-primary: rgb(24, 24, 27);
--color-background-secondary: rgb(34, 35, 38);
--color-border: rgb(49, 48, 53);
--color-accent: rgb(85, 214, 121);
--shadow-alpha: 0.25;
--spinner: var(--color-accent);
}
:root {
--color-text-primary: rgb(105, 105, 105);
--color-text-secondary: rgb(0, 0, 0);
--color-background-primary: rgb(242, 247, 249);
--color-background-secondary: rgb(255, 255, 255);
--color-border: rgb(222, 222, 222);
--color-accent: rgb(147, 51, 234);
--shadow-alpha: 0.025;
--spinner: var(--color-accent);
}
.controls-box {
color: var(--color-text-primary);
background-color: var(--color-background-primary);
}
:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 4px;
}
.button-row {
display: flex;
align-items: center;
gap: 0.75rem;
position: absolute;
top: 0;
margin-top: 12px;
margin-right: 15px;
padding-left: 55px;
}
.button {
font-size: 1.5rem;
border-radius: 99em;
padding: 0;
border: 0;
display: grid;
grid-template-columns: 1fr;
place-items: center;
cursor: pointer;
width: 3.5rem;
height: 3.5rem;
transition: color 0.15s ease, width 0.25s ease-out;
position: relative;
background-color: var(--color-background-secondary);
border: 1px solid var(--color-border);
box-shadow: 0 4px 8px 5px rgba(0 0 0/var(--shadow-alpha));
}
.button--play {
width: 4.5rem;
height: 4.5rem;
position: relative;
}
.button--play:after {
content: "";
display: block;
width: calc(100% + 6px);
height: calc(100% + 6px);
z-index: -1;
left: -3px;
top: -3px;
position: absolute;
background-image: conic-gradient(transparent, var(--spinner));
border-radius: 99em;
opacity: 0;
}
.button--play .ph-play,
.button--play .ph-pause {
grid-row-start: 1;
grid-column-start: 1;
transition: opacity 0.15s ease, transform 0.25s ease;
}
.button--play .ph-play {
opacity: 1;
}
.button--play .ph-pause {
opacity: 0;
transform: rotate(0);
}
.button--play.is-active .ph-play {
opacity: 0;
transform: rotate(180deg);
}
.button--play.is-active .ph-pause {
opacity: 1;
transform: rotate(180deg);
}
.button--play.is-active:after {
opacity: 1;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
.button:hover {
color: var(--color-text-secondary);
}
.button.is-active {
color: var(--color-accent);
}
.theme-toggle {
display: flex;
align-items: center;
gap: 0.5rem;
border-radius: 99em;
background-color: var(--color-background-secondary);
padding: 0.375em 1em;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
display: none;
}
.theme-toggle:hover {
color: var(--color-text-secondary);
display: none;
}
.theme-toggle:has(input:focus-visible) {
outline: 2px solid var(--color-accent);
outline-offset: 4px;
display: none;
}
.theme-toggle i {
flex-shrink: 0;
display: none;
}
.theme-toggle input {
clip: rect(0 0 0 0);
-webkit-clip-path: inset(50%);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
display: none;
}
@-webkit-keyframes spin {
100% {
transform: rotate(360deg);
z-index: -2;
}
}
@keyframes spin {
100% {
transform: rotate(360deg);
z-index: -2;
}
}
body {
background-color: #EEEEEE;
/** Prevents white gap around the table **/
}
div.SongList {
background-color: #EEEEEE;
/** TO AVOID WHITE GAPS or Any Gaps... **/
/** ... Keep synced with "border-color" & body "background-color" **/
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
width: 450px;
height: 400px;
text-align: left;
border: 20px solid #EEEEEE;
/*border-collapse: collapse;*/
margin-top: 100px;
/*padding-top: 40px;*/
}
.Tracks-Title {
font-size: 15px;
color: #A0A0A0;
/** font colour **/
margin-top: 10px;
border-bottom: 1px solid #CDCDCD;
padding: 16px 16px;
/** Top — Left **/
}
.Tracks-Time {
font-size: 9px;
color: darkgrey;
/** Lighter than 'grey' for some reason **/
border-bottom: 1px solid #CDCDCD;
padding: 6px 6px;
letter-spacing: 1.5px;
}
.Table-Buttons {
/** Social — Share — Download **/
font-size: 15px;
color: #A0A0A0;
/** font colour **/
margin-top: 10px;
border-bottom: 1px solid #CDCDCD;
padding: 16px 16px;
/** Top — Left **/
}
.divTableRow:hover {
font-weight: bolder;
/*background-color: #f5f5f5;*/
/** Optional **/
}
.SongList .tableFootStyle {
font-size: 14px;
}
.SongList .tableFootStyle .links {
text-align: right;
}
.SongList .tableFootStyle .links a {
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
.SongList.outerTableFooter {
border-top: none;
}
.SongList.outerTableFooter .tableFootStyle {
/* padding: 3px 5px; */
}
.divTable {
display: table;
}
.divTableBody {
display: table-row-group;
}
.divTableHeading {
display: table-header-group;
}
.divTableRow {
display: table-row;
}
.divTableFoot {
display: table-footer-group;
}
.divTableCell,
/** Default Cell Name... **/
.divTableHead {
display: table-cell;
}
.Tracks-Title,
/** ...Changed it to This **/
.divTableHead {
display: table-cell;
}
.Tracks-Time,
/** This **/
.divTableHead {
display: table-cell;
}
.Table-Buttons,
/** and This **/
.divTableHead {
display: table-cell;
}
<audio id="myAudio" src="data-src">
Your browser does not support the audio element.
</audio>
<div class="button-row">
<button class="button | button--toggle" onclick="shuffle()">
<i class="ph-shuffle"></i>
</button>
<button class="button" onclick="skipBack()">
<i class="ph-rewind"></i>
</button>
<button class="button | button--toggle button--play" onclick="togglePlay()">
<i class="ph-play"></i>
<i class="ph-pause"></i>
</button>
<button class="button" onclick="skipForward()">
<i class="ph-skip-forward"></i>
</button>
<button class="button | button--toggle" onclick="repeat()">
<i class="ph-repeat"></i>
</button>
</div>
<label class="theme-toggle">
<input type="checkbox" onchange="changeTheme(this)">
<i class="ph-lightbulb"></i>
<span>Change theme</span>
</label>
<p>
<p>
<p>
<div class="divTable SongList">
<!--- Outer --->
<div class="divTableBody">
<!--- Inner --->
<!---------- FIRST ROW ------------>
<div class="divTableRow">
<div class="Tracks-Title">
<a href="#" id="song" data-src="https://coleycodes.cloud/player/songs/DangerousWoman.mp3">
Dangerous Woman
</a></div>
<div class="Tracks-Time">0:00</div>
<div class="Table-Buttons">
Buttons Here
</div>
</div>
<!----------->
<!------ END ROW ----->
<!----------->
<!---------- ROW ------------>
<div class="divTableRow">
<div class="Tracks-Title">Into You</div>
<div class="Tracks-Time">0:00</div>
<div class="Table-Buttons">
Buttons Here
</div>
</div>
<!----------->
<!------ END ROW ----->
<!----------->
<!---------- ROW ------------>
<div class="divTableRow">
<div class="Tracks-Title">Side to Side (ft. Niki Minaj)</div>
<div class="Tracks-Time">0:00</div>
<div class="Table-Buttons">
Buttons Here
</div>
</div>
<!----------->
<!----- END ROW ------>
<!----------->
<!--------- ROW ------------->
<div class="divTableRow">
<div class="Tracks-Title">Almost is Never Enough</div>
<div class="Tracks-Time">0:00</div>
<div class="Table-Buttons">
Buttons Here
</div>
</div>
<!----------->
<!----- END ROW ------>
<!----------->
<!----------- ROW ----------->
<div class="divTableRow">
<div class="Tracks-Title">Track Title</div>
<div class="Tracks-Time">0:00</div>
<div class="Table-Buttons">
Buttons Here
</div>
</div>
<!----------->
<!------ END ROW ----->
<!----------->
<!---------- ROW ------------>
<div class="divTableRow">
<div class="Tracks-Title">Track Title</div>
<div class="Tracks-Time">0:00</div>
<div class="Table-Buttons">
Buttons Here
</div>
</div>
<!----------->
<!----- END ROW ------>
<!----------->
<!---------- ROW ------------>
<div class="divTableRow">
<div class="Tracks-Title">Track Title</div>
<div class="Tracks-Time">0:00</div>
<div class="Table-Buttons">
Buttons Here
</div>
</div>
<!----------->
<!----- END ROW ------>
<!----------->
<!----------- ROW ----------->
<div class="divTableRow">
<div class="Tracks-Title">Track Title</div>
<div class="Tracks-Time">0:00</div>
<div class="Table-Buttons">
Buttons Here
</div>
</div>
<!----------->
<!------ END ROW ----->
<!----------->
<!---------- ROW ------------>
<div class="divTableRow">
<div class="Tracks-Title">Track Title</div>
<div class="Tracks-Time">0:00</div>
<div class="Table-Buttons">
Buttons Here
</div>
</div>
<!----------->
<!------ END ROW ----->
<!----------->
</div>
<!---- Inner ---->
</div>
<!---- Outer ---->