0

I am trying to add audio to text to be played on click (in the background) and pause on click again (To read the text on the click)

The website is made with WordPress.

I have entered this script using wp code snippet plugin, and sat the functionality to be played over site header and in posts, I am trying to enter something like this

var yourAudio = document.getElementById('yourAudio'),
    ctrl = document.getElementById('audioControl');

ctrl.onclick = function () {

    // Update the Button
    var pause = ctrl.innerHTML === 'pause!';
    ctrl.innerHTML = pause ? 'play!' : 'pause!';

    // Update the Audio
    var method = pause ? 'pause' : 'play';
    yourAudio[method]();

    // Prevent Default Action
    return false;
};
<audio id="yourAudio" preload="none">
<source src="https://cgejordan.com/wp-content/uploads/2023/01/0007.mp3" type="audio/wav" />
</audio>
<a id="audioControl" href="##">Arabic Word 1</a>

<audio id="yourAudio" preload="none">
<source src="https://cgejordan.com/wp-content/uploads/2023/01/0008.mp3" type="audio/wav" />
</audio>
<a id="audioControl" href="##">Arabic Word 2</a>

<audio id="yourAudio" preload="none">
<source src="https://cgejordan.com/wp-content/uploads/2023/01/0009.mp3" type="audio/wav" />
</audio>
<a id="audioControl" href="##">Arabic Word 3</a>

code reference: https://stackoverflow.com/a/7639343

But texts are not playing the audios when clicked

Could you please assist on how to make it work? and to keep the same text without changing it to Play! Pause! when clicked? just play and pause audio on word click

And do you suggest a better way to add audios into texts without making the page too large \slow?

I have tried many plugins but nothing worked as needed

Moishy
  • 3,560
  • 3
  • 23
  • 42
CGE ADMIN
  • 1
  • 1
  • IDs need to be unique, you can not use the same ID for multiple elements. So the first thing to do here would be to rewrite this so that it works based on classes, and / or the relation the elements have to each other in the DOM. – CBroe Jan 19 '23 at 09:24
  • @CBroe would you please provide me with a clean built code to do this? I have tried many things but nothing worked – CGE ADMIN Jan 19 '23 at 09:32
  • don't you need some javascript .play() method called for them to play? – Rick Jan 19 '23 at 15:41

1 Answers1

0

I recommend using a generator function for each audio element, this generator function should store a reference for the audio element and then use this reference to play the correspondent audio once a word or button is clicked.

Here there's an example of such generator function.

A key point is that you should structure your data in a way you can easily reference both audio source and text. This can be achieved with an arrayand you can use the following object shape:

{ key: '...', text: 'Some text' }

After that the generation function uses a target container for inserting the audio/button containers and each container leverages an event listener that triggers its own audio file and play/pauses according to its current play state.

Note: Preview the following snippet in full page mode to properly see the example

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<style>
  .btn--active {
    background: #db3535 !important;
  }
</style>

<body>
  <div 
    id="audio-root"
    class="flex flex-col items-center justify-center h-screen bg-gray-100"
  ></div>
</body>
<script>
    const data = [
      {
        audioSrc: "https://cgejordan.com/wp-content/uploads/2023/01/0007.mp3",
        text: "Arabic Word 1"
      },
      {
        audioSrc: "https://cgejordan.com/wp-content/uploads/2023/01/0007.mp3",
        text: "Arabic Word 2"
      },
      {
        audioSrc: "https://cgejordan.com/wp-content/uploads/2023/01/0007.mp3",
        text: "Arabic Word 3"
      },
    ];
    
    /**
     * @param {HTMLElement} root
     * @param {Array} data
     */
    function generateAudioElements(root, data)  {
      data.map((item) => {
        const id = crypto.randomUUID();
        const container = document.createElement("div");
        const audioElement = document.createElement("audio");
        const textElement = document.createElement("button");

        const textElementClasses = "mt-2 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
        textElement.classList.add(
          ...textElementClasses.split(" ")
        )
        audioElement.src = item.audioSrc;
        audioElement.controls = true;
        audioElement.textContent = item.text;
        audioElement.id = id;
        textElement.textContent = item.text;
        textElement.addEventListener("click", (event) => {
          const audio = document.getElementById(id);
          // toggle play state
          if (audio.paused) {
            audio.play();

            // Styles
            event.target.classList.add('btn--active');
          } else {
            audio.pause();

            // Styles
            event.target.classList.remove('btn--active');
          }
        });

        container.appendChild(audioElement);
        container.appendChild(textElement);

        root.appendChild(container);
      });
    }
    
    generateAudioElements(document.getElementById("audio-root"), data);
</script>
</html>
Daniel Rodríguez Meza
  • 1,167
  • 1
  • 8
  • 17