Grow your CSS skills. Land your dream job.

Don’t Stop The Music: Links on Pages Playing Audio

Published by Chris Coyier

Over at ShopTalk, we've gotten a number of requests from folks that wished links in our show notes would open in a new tab. They've gotten burned by clicking a link on the page while listening to a podcast via our embedded player. When the browser leaves our page and goes to the link, the audio stops playing. We can do something about that.

One option would be to literally apply a target attribute to each link, so that those links open in a new window or tab.

<a href="#" target="_blank">Show Note Link</a>

We would have to go through our whole archive of shows to add that right to the HTML. Not un-doable, but not great and also not very flexible.

Personally I don't generally like new tab links and I think that's the general UX consensus as well. Don't mess with the default unless you have a good reason. We do have a good reason here, but if we think a bit more about it, what we're actually trying to do here is prevent the sound from abruptly stopping. So let's only alter that behavior when the audio is actually playing.

We're using MediaElements.js for the player and also jQuery on the page. This player provides events we can bind to for starting and stopping of audio.

var player = $('audio').mediaelementplayer();

$(player).on("play", function(event) {

  // Links in new tabs
  $("a").attr("target", "_blank");

});

Cool. You could get fancier with that, by removing the attribute on pause. I'll let you decide how you want to handle it.

But what if you hate changing default behavior like this? That's understandable. There is another way we could do this, and that's using the onbeforeunload event (fires when the browser is about to change pages) to confirm the navigation.

It's plenty easy. We just need to remove it when the audio isn't playing.

var player = $('audio').mediaelementplayer();

$(player).on("play", function(event) {

  window.onbeforeunload = function() {
    return "The podcast will stop playing if you navigate away.";
  }

}).on("pause", function(event) {

  window.onbeforeunload = void(0);

});

Both ways work. I went with the target="_blank" technique for ShopTalk, but CodePen uses onbeforeunload quite a bit when you have unsaved changes to work, to prevent you from losing it. Also related: in the past we've bent over backwards making a whole site Ajax to prevent audio from stopping as you navigated around.

Comments

  1. Awesome solution, Chris! AJAX/Canvas seemed the only feasible option to me, but looks like I’m wrong. Learn something new everyday! On the even more positive side, this is far quicker than cutting deep in to your site with AJAX.

    Cheers!

  2. Permalink to comment#

    I always really like when someone uses something that seems so simple as a solution to a problem. I like that you are using the built-in functionality of MediaElements.js to only apply the target=”_blank” (or the confirmation box) when you are actually playing the audio, but not when it has been paused.

    A quick post for you I suppose, but it gets the brain juices flowing :)

  3. fabrik
    Permalink to comment#

    Why not make use of pushstate and change the content dynamically? Both “solutions” mentioned here has the caveats while pushstate elegantly bypass the problem perfectly.

    • Sure. That’s also a huge infrastructure solution to a little problem. And it also doesn’t solve third party links.

    • While pushstate wouldn’t solve the problem of third-party links, it really isn’t that complicated.

      I wrote an article on using it with jQuery and it only takes about 50 lines.

    • It would be interesting to extend this on a site such that it didn’t have to load the entire page, but literally just the contents. Like expose an API that returns just the content and not the header and sidebar and footer and all that other stuff you don’t need. With WordPress you could likely test if it’s an ajax request in the PHP and just return the_content() (and whatever else you need). Or better, use the JSON api plugin and redirect to that and get the data in a nice JSON format.

    • That’s part two!

      Not sure about using JSON. Wouldn’t that mess with jQuery’s .load?

    • Nice! It probably would, but you just use $.getJSON or whatever since you’d know what format it’s in.

    • I’m curious as to what the advantages of using JSON would be… would you even be able to preserve HTML content inside the article using it?

    • The advantage would be that you would have all these nice separated bits of content to use. Perhaps the site design isn’t simple enough to allow you to just swap out this one big main content section with another block of HTML. If you return the data as JSON, you could have the title and date and author and article and comments or whatever as separate bits, and replace them on the page as needed. Scalpel vs Sledgehammer.

    • Ah! I didn’t think of that. That would be really useful. I had to include the <title> as part of the HTML I returned, so JSON would have helped there.

      However it is also worth noting that you can use selectors with .load, so you could just dump bits of HTML one after another, and target them. But definitely not as clean as JSON.

    • The selectors with .load thing is a cool trick, but that’s exactly the problem with “loading too much.” To use multiple selectors, you’d have to load over and over again multiplying the problem.

    • Hmm. I assumed jQuery would have a way for me to pass in the XMLHttpRequest rather than the URL or something like that to cache the response. Maybe not.

  4. Paulo José
    Permalink to comment#

    There are also the possibility to save the playing time position, so it can be recovered it in the new page. A simply variable in the new URL may the enough. Something like:

    User clicks a link;
    A js handler adds “?play=1234″ to the new URL;
    In the new page, a js function verifies if there are a “play” variable valid and controls the player to resume the previous time.

    It’s for internal links only.

  5. Permalink to comment#

    I personally prefer any link that is going to take me some other website to open in a new tab. To that effect, I Cmd+click pretty much every link knowing that most UX experts (all 3 of them) and those entering content into WordPress don’t use target=”_blank”, rel=”external” or whatever their solution.

    If I’m reading a physical magazine and I pick up another magazine to read something in it, it doesn’t erase my old magazine and cover all of the pages up with the new one. Real life is nothing but new tabs.

    • @Nathan: Makes sense. I’d actually prefer seeing some sort of indication that the link will open in a new tab. Sort of freaks me out when links open up in new tabs unannounced.

  6. Permalink to comment#

    avid ctrl+clicker here too. I don’t like to disturb what I have open or what I am doing, often even on internal links but almost always on external.

    • Permalink to comment#

      Actually, I usually just click with the mouse wheel, unless I am on a laptop of sorts

  7. Permalink to comment#

    I’m going to play devil’s advocate and say that this is a perfect example of a UX situation where target=_blank is not only entirely appropriate, but also the correct and preferred solution.

    Instead of every link opening a new window [tab], however, the podcast should open in a new window [tab].

    A podcast belongs to a player, not a webpage. It should logically be completely separate from web navigation (not just navigation via links). Putting it in its own window [tab] leaves the user free to do anything, including using the back button or address bar.

    I’d also suggest that having the player in a separate window would lend the impression that it’s its own “application,” as native media players are – because of this resemblance, I wouldn’t anticipate much confusion or inconvenience.

    It’s painless to implement, and it degrades quite gracefully.

  8. Permalink to comment#

    Wouldn’t it be better to just use the target attribute, then to have a pop-up confirming that the user wants to leave? In my 7 years of browsing the world wide web, if you leave a page that has audio or video, you usually expect to lose the audio or video.

    Or check out this crazy solution. A user goes to an episode page, they click the listen button, a new predefined window opens which has a player in it. Allowing people to navigate throughout the website, while still having the option to control the audio? I have experienced this on many radio websites, just a thought.

  9. Permalink to comment#

    I thought when people listen to the audio online they click Play and start browsing the web. You surprised me

  10. Well taking the extra step to make a customized player that considers user actions shouldn’t be so difficult.

  11. Maciej Baron
    Permalink to comment#

    It usually is a bad idea to use href="#". Is there a specific reason why you’re doing that? Usually a lot better idea is to leave the href out and simply apply a pointer attribute in the CSS, instead of adding a href just to get a mouse pointer when you hover over it.

  12. dj
    Permalink to comment#

    @Chris Wow. I didn’t mean to start something this big when I suggested this to you. However, it’s nice to feel heard. I do understand some people’s issue with opening a new window or tab BUT, for me, I get more pissed when a sub-link on a site screws with what I’m already doing (ie changes the page) more than when one merely opens what I’ve clicked in a new tab. Partly because then clicking the back arrow requires a new page render and often a new upload, while merely clicking close on the new tab instantly brings back what I was doing without delay.

    Notice, I’m NOT talking about tab’s/window’s opening without me voluntarily clicking on some kind of link to initiate it. In the case of ShopTalk – it seems to me that the “reasonable man” standard would be that clicking on the player means the person wants to listen but not that they want to stop being able to browse to other links – which, by definition, gives you permission to open a new tab. To sort of borrow a quote from you – the “don’t overthink it audio player.” [I do understand that YOUR solution must involve some scripting which accounts for lots of previous post's HTML however.]

  13. I think it’s a little weird only having pages open in a new window when the audio is playing. I would say you either have external sites opening in new windows or you don’t. Like the confirmation solution though that’s slick – as long as it doesn’t fire when somebody chooses to open it in a new window.

  14. It’s amazing how helpful a simple alert can be in this situation. Thanks for sharing!

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".