0

I suspect there is something basic about JavaScript parameter passing that I do not understand.

If I click on this button, I get an 'undefined' message in the alert box.

<button onclick="play_audio(this.src)" src="foo.m4a">▶</button>

If I click on this button, the string value is passed properly:

<button id="foo.m4a" onclick="play_audio(this.id)">▶</button>

Codepen here:

https://codepen.io/anon/pen/JBpMYo

Jonathan
  • 665
  • 5
  • 12
  • 2
    That’s because there is no `HTMLButtonElement.prototype.src`. `this.getAttribute("src")` would “work”, but use `data-src="foo.m4a"` and `this.dataset.src` instead. – Sebastian Simon Jul 31 '18 at 15:58
  • thanks. is there any reason i should want ids for my buttons? i'm trying to keep the markup simple and make it as easy as possible for people to add buttons. – Jonathan Jul 31 '18 at 16:00
  • 1
    @Jonathan The only reason is if you want to uniquely identify a specific button, however you can do that a thousand different ways, id is just the fastest DOM lookup with `getElementById()` – mhodges Jul 31 '18 at 16:02
  • 1
    Then I’d recommend using _only_ the `data-src` attribute. Don’t use `onclick`. Instead, add a button, and add its `data` attribute. Then, use event delegation: `document.addEventListener("click", function(e){ if(e.target.matches("button[data-src]")){ playAudio(e.target.dataset.src); } });`. – Sebastian Simon Jul 31 '18 at 16:04
  • Excellent. Codepen illustrating this approach here: https://codepen.io/anon/pen/oMEpwz Now I just have to explore playAudio() ... – Jonathan Jul 31 '18 at 16:09
  • 1
    My comment should’ve said `play_audio`, the function you’re using, instead of `playAudio`. But it would simply look like `function play_audio(src){new Audio(src).play();}`. – Sebastian Simon Jul 31 '18 at 16:14
  • 1
    Related: [Custom attribute works only with `element.getAttribute("attribute")` but not `element.attribute`](https://stackoverflow.com/q/15010981/4642212). – Sebastian Simon Jul 31 '18 at 16:14
  • It works now, using `new Audio(e.target.dataset.audio).play();` https://codepen.io/anon/pen/oMEpwz – Jonathan Jul 31 '18 at 17:19

1 Answers1

1

A button does not have a src attribute. However, you can use this.getAttribute('src').

<button src="foo.m4a" onclick="play_audio(this.getAttribute('src'))" >▶</button>
<script>
function play_audio(src){
  console.log("Playing "+src);
}
</script>

It is recommended that you usedata-src (you can use any prefix after data-, not necessarily src) and this.dataset.src instead (you can use the data-* attribute to embed custom data) because it will ensure that your code will not clash with HTML Element attributes for future editions of HTML. See the documentation.

<button data-src="foo.m4a" onclick="play_audio(this.dataset.src)" >▶</button>
<script>
    function play_audio(src){
      console.log("Playing "+src);
    }
</script>
Unmitigated
  • 76,500
  • 11
  • 62
  • 80