0

I have the following code that plays and pauses an audio file when the button is clicked. This works fine, but I want to add more buttons with different audio on the same page. How do I control the audio.src from the button instead of within my javascript as I am doing now?

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body{ background:#666; }
button{ border:none; cursor:pointer; outline:none; }
button#playpausebtn{
    background:url(images/play.jpg) no-repeat;
    width:200px;
    height:200px;
}
</style>
<script>
// Main Player Function
    var audio, playbtn;
    function player(){
    audio = new Audio();
    audio.src = "audio/losing.mp3";
    // Set object references
    playbtn = document.getElementById("playpausebtn");
    // Add Event Handling
    playbtn.addEventListener("click",playPause);
    //Functions
    function playPause(){
        if(audio.paused){
            audio.play();
            playbtn.style.background = "url(images/pause.jpg) no-repeat";
        } else {
            audio.pause();
            playbtn.style.background = "url(images/play.jpg) no-repeat";
        }
    }
}
window.addEventListener("load", player);
</script>
</head>
<body>
<button id="playpausebtn"></button>
</body>
</html>
JSS
  • 3
  • 2

2 Answers2

0

maybe this helps.

http://developer.appcelerator.com/question/84241/dynamically-assign-listener-to-button

but it seems you are approaching wrong to problem...

tanaydin
  • 5,171
  • 28
  • 45
0

You could add a property (where you specify the file to be played) and put all buttons in the same class then in the Javascript get all the buttons of that class and then add a eventlistener that plays the file that you get from the property. If you don't understand i can specify more details! I'm not at the pc right now to test it :(

This code works on the last version of Safari, but I think it should work in any browser:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>soundboard</title>
    </head>
    <body>
        <button class="soundBt" name="xxx.mp3">xxx</button>
        <button class="soundBt" name="yyy.mp3">yyy</button>
    <script>
    window.addEventListener("load", setListeners());
    /* this line dinamically adds a method to the String object 
     * working on the prototype of the object
     */
    String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
    var audio = new Audio();
    function setListeners(){
      var index = 0;
        var buttons = document.getElementsByClassName("soundBt");
        for (index = 0; index < buttons.length; index++){
            var button = buttons[index];
            button.addEventListener("click", function(){
                var buttons = document.getElementsByClassName("soundBt");
                var index = 0;
                for (index = 0; index < buttons.length; index++){
                    buttons[index].style.background = "url(images/play.jpg) no-repeat";
                }
                if(audio.paused){
                    var fileToPlay = this.getAttribute("name");
                    audio.src = fileToPlay;
                    audio.play();
                    this.style.background = "url(images/pause.jpg) no-repeat";
                } 
                else{ 
                    audio.pause();
                    this.style.background = "url(images/play.jpg) no-repeat";
                }
            });
        }
    }
    audio.addEventListener("ended", function(){
        var buttons = document.getElementsByClassName("soundBt");
        var index = 0;
        for (index = 0; index < buttons.length; index++){
            var button = buttons[index];
            var buttonName = button.getAttribute("name");
            var audiosrc = audio.src;
            if (audio.src.endsWith(buttonName)){
                button.style.background = "url(images/play.jpg) no-repeat";
                return;
            }
        }
    });
    </script>
    </body>
</html>

I tested it in safari, chrome and firefox. I don't use any strange js feature so it should work in any browser that supports the Audio object. I even tested it against w3c validator and it's valid. In this way you can add all the buttons you want, specifying the class "soundBt" and setting the filename in the name attribute of the button. At load the script will look for every button that has class "soundBt" and add a listener to it that plays the file set in the name attribute (you can see the use of the this keyword that works because addEventListener is a method of the button itself). Obviously this code doesn't check if the file exists or if you've set a name attribute in the button. You can do these checks yourself ;)

In this version I added the change background to the play button when the audio is ended, anyway this solution may become really slow if you have a lot of buttons (DOM parsing is heavy). If you have efficiency issues you could try to put all the buttons in a global map where the keys are the filenames (or button names) and the values are the buttons themselves.

Let me know if this works for you!

tmnd91
  • 449
  • 1
  • 6
  • 23
  • I tried assigning the audio file names to "data-track" within the button tags and then using getAttribute to bring it back to the JavaScript. I could get one button to work, but no more. I've never used getAttribute, but seems it will only work with the first button. – JSS Nov 28 '14 at 23:05
  • Yes, thank you, that does work. The only issue that I have now is with the play/pause feature. I added an id to the button so I could control the appearance with css, but when the first button is playing audio and you click on it to pause, the "pause.jpg" image displays on the second button. If I add a third button, it displays there. You probably didn't notice it if you don't have the actual play/pause images. How do you solve that? – JSS Nov 29 '14 at 12:08
  • I think I just solved my own problem by changing "button.style.background" to "this.style.background" and now the buttons are behaving as intended. One more question on this: When I click a button and the audio plays to the end, how do I get the image to switch back to the "play.jpg"? Right now it will just sit on the "pause.jpg" image when it's done. – JSS Nov 29 '14 at 12:29
  • Yes, this Instead of button is the way. To change the background back i think you should have to addEventListener to the audio object and when it stops playing (there should be an event for that) you read audio.src, look for the button that has that name and change its background. I can't code it because i'm on the phone right now. But i think it's more difficult to explain than to do ;) – tmnd91 Nov 29 '14 at 12:54
  • I will play around with it. If I figure it out, I'll post it. – JSS Nov 29 '14 at 13:07
  • No luck. Every time I try to addEventListener with "ended" the entire script won't run at all. I'm not sure if I should be placing it within the setListeners function or if it's totally separate. – JSS Nov 29 '14 at 14:53
  • I updated the answer, that code changes the background at the end of the play. You should accept the answer if it solved your problem ;) – tmnd91 Nov 30 '14 at 10:41
  • Thank you. The updated code changes the image back when done playing. Here is a link to see this example live [link]http://www.hatfulofrain.com/lab/sound-test.html Notice how when you let the one of the buttons play out to the end and then you click on another button nothing happens until you click on it a second time. Is there an easy fix for that? – JSS Nov 30 '14 at 11:44
  • Just set all buttons to the play style before setting a new pause style ;) I edited and fixed the code. now that you need that set of buttons a bunch of times, i recommend to save them into a global map the first time you look for them ;) – tmnd91 Dec 01 '14 at 07:32
  • Thanks, that fixed the issue. All of the buttons will eventually have different graphics that will match the audio they contain. – JSS Dec 01 '14 at 21:01