0

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 ---->

5
  • 2
    You need to DELEGATE but also you need to ask ONE question at a time.
    – mplungjan
    Commented Apr 12 at 8:41
  • 1
    So you want us to help you recover from a lack of version control? Given that you already had a lot of this functionality, what's stopping you from re-writing it (potentially more efficiently, since you've done it once already), where are you specifically stuck? What programming help do you need? Commented Apr 12 at 8:44
  • Well the missing code was mostly copied from other music players that were seemingly similar, & more or less, tweaked here & there (& I am working on doing that now, realising it may be more important TO have as close to the correct code as possible) Commented Apr 12 at 9:21
  • well I suppose I am stuck with mostly the JavaScript (& any HTML that may be directly corresponding with any additional JavaScript that is part of my solution) Commented Apr 12 at 9:25
  • You need to narrow it down to one specific problem - and therefore one specific question - per post on Stack Overflow. So, work out what problem you (first) want help with, focus your question on that specific issue, explain what's wrong with your current code (whether it throws errors, does something you don't expect...) and specify your desired result. Please read the "How to Ask," and the "minimal reproducible example," guidance and then edit your question. As it stands, there's too much noise in the question, not enough focus, and too many questions for us to provide an answer. Commented Apr 12 at 12:44

0

Browse other questions tagged or ask your own question.