skip to Main Content

Everything is working fine, only audioElement1 is not getting paused which is described in the else statement, although the other feature of changing image written in the same else statement is working fine…. so how is this happening…. I am confused.

My HTML

<div class="second-song-list">
        <img class="second-img" src="images/covers/1.jpg" alt="" />
        <div class="second-song-name">Warriyo - Mortals [NCS Release]</div>
        <div>4:03
          <img id="1"
            class="second-icon"
            src="images/circle-play-regular.png"
            alt="play/pause"
            srcset=""
          />
        </div>
      </div>
      <div class="second-song-list">
        <img class="second-img" src="images/covers/2.jpg" alt="" />
        <div class="second-song-name">Cielo - Huma-Huma</div>
        <div>4:43
          <img id="2"
            class="second-icon"
            src="images/circle-play-regular.png"
            alt="play/pause"
            srcset=""
          />
        </div>
      </div>

My javascript

for (n = 0; n <= 9; n++) {
  var icon = document.querySelectorAll(".second-icon");

  icon[n].addEventListener("click", (e) => {
    var x = e.target.getAttribute("id");
    audioElement1 = new Audio("songs/" + x + ".mp3");
    if (e.target.getAttribute("src") == "images/circle-play-regular.png") {
      e.target.setAttribute("src", "images/circle-pause-regular.png");
      audioElement1.play();
    } else {
      audioElement1.pause();
      e.target.setAttribute("src", "images/circle-play-regular.png");
    }
  });
}

2

Answers


  1. On each click you create a new Audio element:

    for (n = 0; n <= 9; n++) {
      // ...
      icon[n].addEventListener("click", (e) => {
        // ...
        audioElement1 = new Audio("songs/" + x + ".mp3");
        if (e.target.getAttribute("src") == "images/circle-play-regular.png") {
          // ...
        } else {
          audioElement1.pause();
          e.target.setAttribute("src", "images/circle-play-regular.png");
        }
      });
    }
    

    So the one that you "pause" doesn’t actually exist. You probably just need to define `audioElement1′ before the click handler and then wrap it in a closure or something to preserve the reference (since you are sharing the variable for each audioElement).

    for (n = 0; n <= 9; n++) {
      var x = e.target.getAttribute("id");
      audioElement1 = new Audio("songs/" + x + ".mp3");
      (function(audioElement1, n) {
        icon[n].addEventListener("click", (e) => {
        
          if (e.target.getAttribute("src") == "images/circle-play-regular.png") {
          // ...
          } else {
            audioElement1.pause();
            e.target.setAttribute("src", "images/circle-play-regular.png");
          }
        });
      })(audioElement1, n);
    }
    
    Login or Signup to reply.
  2. It’s easier just to have the <audio> tag in HTML and hide it by not adding controls attribute to it. Having only one variable audioElement1 to reference multiple Audio Objects is totally unnecessary (I thought impossible because it sounds ludicrous). Just to show other readers, in the example below the fourth <audio> has controls attribute. To prevent an exception, there’s a dummy <button> that cannot be seen nor clicked. It’s there since the event handlers on the <audio> expect a <button> — normally you’d have it one way (all hidden) or the other (all visible).

    Details are commented in example

    // String is the common path to mp3s
    const base = "https://assets.mixkit.co/sfx/preview/";
    /*
    This is an array of objects, each object has properties with unique
    values
    title to <figcaption>
    time to <time>
    file to <audio> which is interpolated to >base<
    */
    const list = [{
      title: "Arcade retro game over",
      time: "00:01",
      file: "mixkit-arcade-retro-game-over-213.mp3"
    }, {
      title: "Cinematic laser gun thunder",
      time: "00:04",
      file: "mixkit-cinematic-laser-gun-thunder-1287.mp3"
    }, {
      title: "Small group cheer and applause",
      time: "00:10",
      file: "mixkit-small-group-cheer-and-applause-518.mp3"
    }, {
      title: "Aggressive beast roar",
      time: "00:01",
      file: "mixkit-aggressive-beast-roar-13.mp3"
    }];
    
    // Collect all <audio> into a NodeList
    const mp3s = document.querySelectorAll("audio");
    /*
    Each <audio> will get a url for it's `src` and will be registered to
    the "playing" and "pause" events. The event handlers toggle the 
    <button> associated with the <audio>.
    */
    mp3s.forEach((audio, index) => {
      audio.src = `${base}${list[index].file}`;
      audio.onplaying = e => btns[index].classList.add("pause");
      audio.onpause = e => btns[index].classList.remove("pause");
    });
    
    // NodeList of <figcaption>
    const caps = document.querySelectorAll("figcaption");
    // Add the associated title
    caps.forEach((caption, index) => caption.prepend(list[index].title));
    
    // NodeList of <time>
    const time = document.querySelectorAll("time");
    // Add the associated time
    time.forEach((time, index) => time.textContent = list[index].time);
    
    // NodeList of <button>
    const btns = document.querySelectorAll("button");
    // Register each <button> to the "click" event when triggered call playPause()
    btns.forEach((button, index) => button.onclick = playPause);
    
    // Event handler that plays and pauses associated <audio>
    function playPause(event) {
      const audio = this.closest("figcaption").querySelector("audio");
      if (audio.paused) {
        audio.play();
      } else {
        audio.pause();
      }
    }
    html {
      font: 300 2ch/1.25 "Segoe UI"
    }
    
    ul {
      list-style: none
    }
    
    figure {
      display: list-item;
      width: max-content;
      margin: 0;
      padding: 0
    }
    
    figure+figure {
      margin-top: 10px;
    }
    
    figcaption {
      padding-top: 5px;
      text-align: center;
    }
    
    audio {
      width: 240px;
      height: 30px;
      margin: 8px 0;
    }
    
    time {
      display: inline-block;
      vertical-align: middle;
      height: 20px;
      margin-bottom: 9px;
      font-family: Consolas;
    }
    
    button {
      display: inline-flex;
      justify-content: center;
      align-items: center;
      padding: 0;
      border: 0;
      background: transparent;
      font-size: 1.75rem;
      cursor: pointer;
    }
    
    button::before {
      content: "▶️";
    }
    
    button.pause::before {
      content: "⏸️"
    }
    <ul>
      <figure>
        <img src="https://placem.at/things?w=240&h=135&random=1&txt=1&txtclr=fc0" alt="" />
        <figcaption>
          <br>
          <audio></audio>
          <time></time><button></button>
        </figcaption>
      </figure>
    
      <figure>
        <img src="https://placem.at/things?w=240&h=135&random=1&txt=2&txtclr=fc0" alt="" />
        <figcaption>
          <br>
          <audio></audio>
          <time></time><button></button>
        </figcaption>
      </figure>
    
      <figure>
        <img src="https://placem.at/things?w=240&h=135&random=1&txt=3&txtclr=fc0" alt="" />
        <figcaption>
          <br>
          <audio></audio>
          <time></time><button></button>
        </figcaption>
      </figure>
    
      <figure>
        <img src="https://placem.at/things?w=240&h=135&random=1&txt=4&txtclr=fc0" alt="" />
        <figcaption>
          <br>
          <audio controls></audio>
          <!--Dummy button-->
          <button style="display: none"></button>
        </figcaption>
      </figure>
    </ul>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search