62

In a project recently when I loaded a sound with

var myAudio = new Audio("myAudio.mp3");
myAudio.play();

It played fine unless a dialogue was opened (ie alert, confirm). However when I instead tried adding an audio tag in my html

<audio id="audio1">
    <source src="alarm.mp3" type="audio/mpeg" />
</audio>

and using

var myAudio1 = document.getElementById("audio1");
myAudio1.play()

it continued to play after a dialogue was opened. Does anyone know why this is? Also more generally what are the differences between the two ways to play sounds?

ekcrisp
  • 1,967
  • 1
  • 18
  • 26
  • Where exactly are you getting the javascript Audio object from? i.e. what library? – Ben Smith Jan 30 '14 at 23:14
  • 3
    Good question, I'm not sure exactly, I followed a few examples from stackoverflow, here are a couple i saw, [ex1](http://stackoverflow.com/questions/3273552/html-5-audio-looping), [ex2](http://stackoverflow.com/questions/9419263/playing-audio-with-javascript), in the latter someone suggested it as a way to play audio "if you don't want to mess with html elements". I thought it was pure js, however I oddly can't find any documentation. The only library I am using is jquery. Clearly the html tag is preferred, I'm still curious about the Audio object though, please post documentation if you find – ekcrisp Jan 31 '14 at 01:41

6 Answers6

26

According to this wiki entry at Mozilla <audio> and new Audio() should be the same but it doesn't look like that is the case in practice. Whenever I need to create an audio object in JavaScript I actually just create an <audio> element like this:

var audio = document.createElement('audio');

That actually creates an audio element that you can use exactly like an <audio> element that was declared in the page's HTML.

To recreate your example with this technique you'd do this:

var audio = document.createElement('audio');
audio.src = 'alarm.mp3'
audio.play();
pseudosavant
  • 7,056
  • 2
  • 36
  • 41
  • can you explain how one would use your example? – Damainman Nov 15 '17 at 22:00
  • @Damainman What are you trying to do? The example I show will create and ` – pseudosavant Nov 16 '17 at 19:51
  • Thanks for replying! In OP example, by manually creating an audio element in html he has control where that element displays in the html. In your example since the html element is dynamically created from the js code, it doesn't explain how the audio element appears in the page. Let me know if what I am saying does not make sense. – Damainman Nov 21 '17 at 05:16
  • 1
    That is a separate concern really. The initial question was about playing audio in JS and why they were seeing something different than doing it in HTML. In my example there is no direct way that the ` – pseudosavant Nov 21 '17 at 17:24
12

JavaScript halts during an Alert or Confirm box.

You cannot concurrently run code and display an alert(), confirm(), or prompt(), it literally waits for user input on this, this is a core feature of JavaScript.

I am assuming it is that very reason why an audio file played entirely within JavaScript scope does this. Comparatively Flash video clips or HTML5 audio/video will continue to play on even when a JavaScript alert/confirm/prompt is open.

As for what method is better, well that is up to you. It is pretty archaic to do anything with the JavaScript built in alert/confirm/prompt anymore, there are way better looking prompts you can make with jQuery UI and so on.

If you have a lot of dynamic content on the page or are you looking into background buffering audio before they need to be triggered and so on, then JavaScript is probably the saner way to go about things.

If you have literally just one player on the screen then there is no excuse for not putting in onto the HTML code. Although unlikely to affect anyone these days, it is still bad practice to rely heavily on JavaScript when there is no reason to.

Nerdroid
  • 13,398
  • 5
  • 58
  • 69
Aaron
  • 394
  • 2
  • 8
2

I came up with the function below from several answers across the web.

function playAudio(url){
  var audio = document.createElement('audio');
  audio.src = url;
  audio.style.display = "none"; //added to fix ios issue
  audio.autoplay = false; //avoid the user has not interacted with your page issue
  audio.onended = function(){
    audio.remove(); //remove after playing to clean the Dom
  };
  document.body.appendChild(audio);
}
Kareem
  • 5,068
  • 44
  • 38
0

If you will create - then you will have problems on ios, because it showing even you will set width:0px

nvvetal
  • 1,756
  • 1
  • 17
  • 19
0

var myAudio = new Audio("myAudio.mp3"); is faster because it does not interact with the DOM.

If you are using multiple audios and/or won't need the user to interact with the player controls you should definetly chose new Audio() where the DOM is not involved.

Azevedo
  • 2,059
  • 6
  • 34
  • 52
0

First let me answer the difference that lies between them. audio tag in html and the new audio object in js, if have a difference is a subtle one and insignificant. They actually do the same thing. If you just want to include an audio inside your webpage, then using the html tag is seem fit and recommended. And If you would like the audio to play whilst there has been an interaction from the user, then the javascript Audio object is seem fit and recommended. For instance; document.querySelector("button).onclick=()=>{let audio=new Audio(audio url); audio.play;

Besides that's the primary purpose of javascript.

Now the reason why the audio still plays when the dialogue opens when you use the html audio tag is because of the fact that the browser first loads your html file, execute the content of the file until it encounters the script tag in the html file and loads the javascript file too. All I'm trying to say is, the audio tag was already read by the browser even before the script loaded. Javascript pauses when an alert(), prompt() or confirm is encountered. Thus "playing fine after an alert was opened". (•‿•).

3NaNa7
  • 51
  • 1
  • 7