www.webdeveloper.com
Results 1 to 5 of 5

Thread: Play a sound on hyperink?

Hybrid View

  1. #1
    Join Date
    Sep 2007
    Posts
    60

    Play a sound on hyperink?

    Hi guys

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

    Code:
    <!--[ 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

  2. #2
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    868
    The <audio> element has an 'ended' event that you could use to trigger this. A simple event listener could trigger your redirect like so:

    Code:
    document.getElementById('audiotag').addEventListener('ended', function() {
    	window.location.href = "http://www.some-new-url.com/and/stuff.html"
    }, false);
    Also, I feel like noting that none of this is really cross-browser compatible. The <audio> tag itself has some setbacks when viewed across multiple browsers (mainly a lack of support in older versions of IE, and file type compatibility in browsers that do support it). And the code above to set the event listener will not work in IE8 or lower (but given that the <audio> tag isn't supported there I didn't feel the need to add IE's old attachEvent() method).
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  3. #3
    Join Date
    Apr 2014
    Posts
    56
    Also, remember that Opera does not support mp3 file format for the <audio> tag. It only supports wav or ogg.

  4. #4
    Join Date
    May 2014
    Posts
    905
    First off, the riot act. Auto-playing noises on websites are annoying garbage that was on pretty much every 'top ten design failure' list of the previous decade. Someone viewing a website while rocking out to Motorhead, Skynrd, Van Halen (not van hagar) -- or wussing out to Celine and Miley - doesn't want your button sound blasting them just because they clicked on a link. It's going to be even more annoying since on something like an anchor you'll have to delay before you allow the new page to load, slowing down the user experience.

    THAT SAID, if this is a applet or maybe a game, THEN there might be a reason to do this... But it's going to take a LOT more work than you think.

    Your code as is has... issues. You're loading scripting only elements in the markup, it has no graceful degradation, and is markup hooking the scripting instead of the scripting hooking the markup.

    Really what you need here is a healthy dose of the "unwritten rule of JavaScript" -- if you can't make a page work without JavaScript FIRST, you likely have no business adding scripting to it.

    To that end, I would have a class to indicate that an anchor should play a sound, and make the rest of it a normal anchor.

    <a href="#" class="clickSound" rel="next">Next Page</a>

    Replacing # with wherever it is you want to go. (that REL is handy in browsers that will let you forward to the first 'next' on the page)...

    It is then a matter of isolating anchors with .clickSound on them, and attaching the method. I would load the audio by generating the element in the JS -- since there is no reason for it to exist in non-js UA's... hooking that sound's ondataloaded to apply the playback event to the anchors. Probably wrap it all in an anonymous function too so it has it's own isolated scope. The playback event would have to cancel bubbling, save the target HREF somehow, then hand off to the play() method. The sound's audio element would need (as Sup3rkirby rightly pointed out) a 'onended' handler, which would then change the window.location.href to the links target href.

    That would go a little something like this:

    Code:
    (function(d) {
    
    	/*
    		any browser that doesn't support these likely doesn't support
    		HTML 5 audio, so we can bomb out early here!
    	*/
    	if (!d.getElementsByClassName || !window.addEventListener) return;
    	
    	var
    		clickSound = d.createElement('audio'),
    		clickFormat,
    		clickTarget = false;
    		
    	/* 
    		If it doesn't have canPlayType, browser doesn't support audio,
    		so bomb out as there's no reason to continue; We also test for 
    		format support so we can choose the correct file type, if neither
    		of our desired audio types is present, bomb out.
    	*/
    	if (typeof clickSound.canPlayType == 'function') {
    		if (clickSound.canPlayType('audio/mpeg')) {
    			clickFormat = 'mp3';
    		} else if (clickSound.canPlayType('audio/ogg')) {
    			clickFormat = 'ogg';
    		} else return;
    	} else return;
    	
    	/*
    		We just made these, no need to waste addEventListener on it.
    		Although we shouldn't have to, it's probably a good idea to
    		attach our handlers BEFORE setting the SRC.
    	*/
    	clickSound.onended = function() {
    		if (clickTarget) window.location.href = clickTarget;
    	};
    	
    	clickSound.onloadeddata = function() {
    		var anchors = d.getElementsByClassName('clickSound');
    		for (var t = 0; t < anchors.length; t++) anchors[t].addEventListener(
    			'click',
    			function(e) {
    				clickTarget = e.target.href;
    				clickSound.play();
    				if (e.preventDefault) e.preventDefault();
    				e.returnValue = false;
    			}
    		);
    	};
    	
    	clickSound.src = 'sounds/button-4.' + clickFormat;
    	clickSound.style.display = 'none';
    	d.body.appendChild(clickSound);
    		
    })(document);
    Which should work in all modern browsers, as well as IE 9/newer. ...pay close attention to how I worded that.

    I put a live demo up here:
    http://www.cutcodedown.com/for_other.../template.html

    As with all my examples the directory:
    http://www.cutcodedown.com/for_others/rJoseph/

    Is unlocked for easy access to the gooey bits and pieces.

    Of course, one of the big hoots about this approach is that since we are detecting by browser capabilities and not markup specification, we can safely do this in a RECOMMENDATION doctype (non-HTML5) and still have 'valid markup'.

    Hope this helps -- I know it's a lot to take in.
    Java is to JavaScript as Ham is to Hamburger.

  5. #5
    Join Date
    May 2014
    Posts
    905
    Oh, and a more versatile version might make that a normal function instead of anonymous, so you could pass it the file prefix (path exclusing extension) and the class to target, so you could have multiple different sounds on different links.
    Java is to JavaScript as Ham is to Hamburger.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles