Play sound on hyperlink?

Hi guys

I’m using this script to play a sound when a link is pressed (I’m viewing it in an iPad):

<!--[ In the head section of the HTML ]-->

<!--audio-->
<script type="text/javascript">
	function play_single_sound() {
			document.getElementById('audiotag').play();
	}
</script>
<!--/audio-->

<!--[ In the body section of the HTML ]-->

<!--embedded audio-->

<head>
<style>
div#audio {
	display: none;
	overflow: hidden;
}
</style>
</head>

<div id="audio">
	<audio id="audiotag" src="http://www.soundjay.com/button/sounds/button-4.mp3" autobuffer="autobuffer"></audio>
</div>
<!--/embedded audio-->

<!--button/link-->
<a href="javascript:play_single_sound();">Next page</a>
<!--/button/link-->

<!--[ Optional CSS ]-->

It works just fine. However, I need to direct the user to another page after the sound is played. Is this possible? If so, how is it done?

Any help would be fully appreciated.

Best regards

Rod from the UK

First things first - the embedded scripting on the link tag is going to give you problems, so let’s deal with that first.


<!--button/link-->
<a href="#" class="nextPage">Next page</a>
<!--/button/link-->

<!--[ At the end of the body section of the HTML ]-->

<script type="text/javascript">
...
</script>

That’s much better. Now your scripting can easily access the next page link, using document.querySelector(‘.nextpage’) or variations thereof.

If you know how long the audio is, such as 1000 milliseconds, then you could do something like this:


function playRedirect(url) {
    play_single_sound();
    setTimeout(function () {
        location.href = url;
    }, 1000);
}

but what would be better is to find out how long the audio is, and wait for it to finish playing.

Using setInterval we can check for the end of the audio being played, which can be done 4 times a second (250 milliseconds), which doesn’t result in any noticeable performance loss of the computer, and is speedy enough to not be noticied by the person using it. We can then load the new page when the end stops increasing. For flexibility, the audio target and the url have been given as variables, so that this code can be used in multiple situations.


setInterval(function () {
    var end = document.getElementById(target).played.end(0);
    if (end > time) {
        time = end;
    } else {
        newPage(url);
    }
}, 250);

For the sake of completion, here’s the new link and the whole script, as a working example.


<audio id="audiotag" src="Brave-Roar.mp3" autobuffer="autobuffer"></audio>


function play_single_sound(target) {
    document.getElementById(target).play();
}

function newPage(url) {
    location.href = url;
}

function playThenRedirectTo(audioTarget, url) {
    var time = 0;

    play_single_sound(audioTarget);

    setInterval(function () {
        var end = document.getElementById(audioTarget).played.end(0);
        if (end > time) {
            time = end;
        } else {
            newPage(url);
        }
    }, 250);
}

document.querySelector('.nextPage').onclick = function () {
    playThenRedirectTo('audiotag', 'http://www.google.com/');
    return false;
}

As a side-note - I had to play Brave Roar many times through as a part of testing this. I am not unpleased.

And now that the underlying work has been done, we can put the actual destination in the link itself, so that the link can be used when the sound stops playing.


<a href="http://www.google.com/" class="nextPage">Next page</a>

With the above, we can now use this.href to get the URL to follow.
For the sake of completion, I’ve also added an appropriate piece at the end, to prevent the link from being followed too.


document.querySelector('.nextPage').onclick = function (evt) {
    evt = evt || window.event;

    playThenRedirectTo('audiotag', this.href);
    
    // prevent the link from being followed, until we want to later on
    if (evt.preventDefault) {
        evt.preventDefault();
    } else {
        evt.returnValue = false;
    }
}

I’m glad that I picked Brave Roar as the audio with which to test this.