Incorporating HTML5 audio elements in JavaScript

I am working on a project where I need to create a grid of 16 audio files with separate links for each in HTML, CSS and JavaScript. Each box in the grid should link to a different audio file.

My initial thought was to use a table to achieve this, so I created one using HTML/CSS. Here is an example of one of the cells (TD) that I used:

<td id="A" class="squareA" type="button";><audio src="music/work_it.wav">Work It</td>

After setting up the HTML structure, I attempted to add event listeners and get elements by tag name using JavaScript but ran into some issues. If anyone has any suggestions or tips, I would greatly appreciate it!


document.addEventListener("DOMContentLoaded", function(event)) {
var audio = document.getElementsByTagName('audio')[0];
  
  workit.addEventListener('click' function());

Answer №1

If you're trying to target the `audio` tag within each `td`, but are lacking a unique identifier, there's a simple solution. By making a small addition to your code, you can easily address this issue.

<td id="A" class="squareA" type="button";>
   <audio id="audio-A">
     <source src="music/work_it.wav" type="audio/wav">
   </audio>
   Work It
</td>

By using specific `id`s, you can now locate each tag effortlessly.

Alternatively, if you include `controls` in the `audio` tag, users will be able to activate the default browser player and play the file without any additional coding.

<audio controls>
   <source ... etc
</audio>

However, if `controls` are absent (or set to `controls="false"`), the default browser player won't appear. If your goal is to play the audio file with a click event, this may be the desired outcome.

At this point, the `id`s of Audio tags might not be useful because without `controls`, nothing will be displayed for users to interact with. In such cases, you would need to target all of their respective `td` elements in the table.

If you haven't already done so, consider adding an `id` attribute to the audio table (e.g., 'audio-table'), allowing you to use `.addEventListener()` on each `td` box with a function called upon page loading:

function addEvents2Table() {
  /* assuming the table has an
     id of 'audio-table' here */
  var audioTable = document.getElementById('audio-table');

  /* collect td tags */
  var tdTags = audioTable.getElementsByTagName('td');
  var len = tdTags.length;

  /* add a 'playAudio' function call
     to each td when clicked */
  while(len--) {
    tdTags[len].addEventListener(
      'click', playAudio, false
    );
  }
}

/* trigger 'addEvents2Table()' on page load */
window.onload = function() {
  addEvents2Table();
};

Now, when a `td` in the table is clicked, the `playAudio()` function will execute. All that remains is to define this function based on your HTML structure:

In the first code snippet provided above, an `id` was added to the audio tag within a td-tag with an `id` of "A." This initial setup will prove valuable now:

function playAudio(event) {
  /* fetch the 'id' of the clicked element */
  var tagID = event.target.id;

  /* append it to 'audio-' */
  var audioID = 'audio-' + tagID;

  /* locate the corresponding audio tag */
  var audioTAG = document.getElementById(audioID);

  /* initiate playback */
  audioTAG.play();
}

There are various considerations to bear in mind moving forward. Are you comfortable with simultaneous audio playback in the browser? Would you like users to stop an audio clip? As currently implemented, clicking multiple boxes rapidly could result in overlapping audio playback attempts. Additionally, clicking a box while its corresponding audio is playing may create issues.

Nevertheless, these suggestions should provide a solid starting point. Feel free to leave a comment if further explanation is needed.

For reference, here is MDN's audio tag page.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can I use a single component for all routes in NextJS?

Just starting out with NextJS and facing a simple problem: I'm wondering if it's possible to achieve the following setup using NextJS // with react-router-dom <Router> <> <Header /> <Switch> & ...

Utilize dynamic inline styling to pass asset image paths as background images in Nuxt.js

I am in the process of developing a Nuxt.js application and I have a requirement to dynamically set the background image of an element using images from the assets folder. Here is what I have implemented: <template> <div> <div v ...

Adjust Mui Autocomplete value selection in real-time

I have implemented Mui AutoComplete as a select option in my Formik Form. <Autocomplete disablePortal options={vendors} getOptionLabel={(option) => option.vendor_company} onChange={(e, value) => {setFieldValue("vendor_id", value. ...

Having trouble retrieving the keyword property within a Vue.js promise

Struggling with an async validation process in Vue.js where I need to globally access the $axios instance, but encountering failures Validator.extend('async_validate_job_type', { getMessage: field => `The Name already exists`, val ...

Having trouble with the functionality of JQuery drop feature?

As I delve into implementing drag and drop functionality with JQuery, I encounter a peculiar issue. I have set up 3 'draggable' divs and corresponding 3 'droppable' divs. The intended behavior is for each draggable element to be accepte ...

Generate an interactive pie chart with visually appealing animations using jQuery, without any actual data

My task involves creating a pie chart to visually display different categories. However, the challenge is that the chart does not contain any data, ruling out options like Google charts or other data-driven chart makers. As a solution, I have turned the pi ...

Determine if the input text field contains any text and store it in a variable using jQuery

I'm working on a form that includes radiobuttons and textfields. To keep track of the number of checked radiobuttons, I use this code: var $answeredRadiobuttons = $questions.find("input:radio:checked").length; But how do I store the number of textf ...

Transform the text color of a table generated by a v-for loop

I have a Vue.js setup to exhibit a collection of JSON data which consists mainly of numbers. These numbers are displayed in a table format, with one minor issue - if the number happens to be negative, the text color of its cell needs to be red. <table& ...

Tips for validating date input in a TextBox using JQuery on an ASP.NET platform:

Here is some code I wrote: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="datetime.WebForm1" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <tit ...

Entity designation experiencing operational difficulties

Having trouble converting my HTML to XHTML. Whenever I replace the greater than sign with &gt;, my if statement stops working properly. The same issue occurs when replacing the ampersand with & and the less than sign with <. Even CDATA isn' ...

JavaScript: End the program upon clicking CANCEL

Scenario: In my application, there is a confirmation pop-up message that appears when I try to save an entry. Clicking the OK button proceeds with saving the entry, while clicking the CANCEL button should go back to the booking content page - this functio ...

Ignoring the incremented value in a jQuery function

I have been struggling to resolve this issue for quite some time now, and unfortunately, my lack of proficiency in javascript is hindering me. Here's a jfiddle with an interesting jquery code snippet that I came across: [html] <button id="addPro ...

Divide and Insert a Gap in Phone Number

I need help formatting a telephone number so that there is a space between every third and seventh character. var phoneNum = "02076861111" var formattedNum = [phoneNum.slice(0, 3), phoneNum.slice(3,6), " ", phoneNum.slice(6)].join(''); console ...

The relevance of this concept in the classroom setting and within the setTimeout function is integral to

Having recently started learning JS, I have gone through various answers on the context of "this" with classes and setTimeout(), but I am facing a specific issue. I am struggling to understand the thought process or mental model behind the following code ...

Async/Await mishap

Could someone please explain why the code below is printing a blank result? I was expecting it to print "done" since I thought the await keyword would make the program wait for the promise to be resolved. Appreciate any help provided! let message = &apos ...

Spicing up javascript with Currie's arrow function

Can you please break down this function in a straightforward way (without using arrows)? I'm having trouble understanding if "foo" in Promise.resolve "foo" is an argument or a callback function. module.exports = function foo(req, res, next) { retu ...

How do I access the previous and current values in a v-for loop in Vue.js in order to compare them?

I am working on a structural component that involves looping through a list and performing certain actions based on the items: .... <template v-for="(item, INDEX) in someList"> <template v-if="thisIsArrayList(item)"> ...

Using React Native to share API and passing a Base64 string in place of an image when sharing to WhatsApp

I am facing difficulties in sharing a base64 image on WhatsApp. On both iOS and Android, the actual base 64 code is shared instead of the image. When I try to use iMessage or Email on iOS, the base64 images are converted and displayed correctly. However, ...

Is there an alternative to using CSS units of measurement when using the .css() method?

Is there a way to use .scrollTop() and .css() to adjust the margins of an element so that it floats up only when the page is scrolled, but stops at a certain margin value? I want the element to float between specific values while scrolling. The issue I am ...

Position the second line of text to align in MUI

I am facing an issue with aligning the text on the second line. It should match up with the text on the first line. For reference, you can check out the Codesandbox by CLICKING HERE <Card sx={{ maxWidth: 200 }}> <CardMedia component="i ...