Latest TweetsDifference between mod_alias and mod_rewrite perishablepress.com/difference…
Perishable Press

Targeting External Links Intelligently

Bill Brown Exclusive guest post by .

[ Young Planet Earth ] In the beginning…

In the time of the dinosaurs, HTML authors controlled the way anchors opened by adding target="_blank" as an attribute on an anchor tag. Then the molten mass of Internet began to cool into the thin crust of Web 2.0, the continents began to separate and there came a great migration of pages from HTML to the shinier, new XHTML. Most authors didn’t know what that meant, but it had an “X” in it, so it must be cool, they thought.

Alas, there came a great despair as the beloved target="_blank" attribute was no longer looked kindly upon by The Great Validator. The new XHTML pages would not wear the Shiny Badge of Validation Love.

Designers, developers and former blink taggers mourned the passing of new windows and slogged on, heads hung low… until March 4th, 2003. On that day, Kevin Yank of SitePoint.com delivered the news that one could use JavaScript to code target="_blank" on all anchors upon which one had set the rel="external" attribute after the pages had loaded. The pages would receive the much sought after blessing of The Great Validator and anchors could open new windows without extensive JavaScripting.

Oh, how the authors rejoiced in the discovery of this new treasure. Then came the Great Usurpers: User Experience Advocates who said, “Thine actions shall bring about the decline of the Great Internet. The choice of _Blank and _Self belongs to the Almighty User.” Once again, a wave of sorrow swept the Internet.

until today.

The New Internet

Website designers and developers have a great many tools at their disposal these days. Like power tools, these things can help or hurt us. In theory, the idea of opening external links in a new window sounds very sane. If everybody used it this idea intelligently, it would be, well, smart.

In fact, I’m surprised my browser doesn’t allow me to specify what to do with links that take me to a different domain. It seems like a reasonable enough expectation.

Moving along, since there’s already scripts out there which set the target attribute to “_blank” and authors who’ve written the tutorials already, so I’ll just get to the point of this script and why it’s different.

Here’s the list of goals and requirements I used in writing this script:

  • Easy – I didn’t want to have to ever touch it again, even to configure it with defaults. I just wanted to include it on the page and be done with it.
  • Easier – I didn’t want to have to set rel="external" on anything. I figured the script should be smart enough to determine if a link is external or interal by comparing the domain of the site with the href of the anchor.
  • Accessible – The user needed to be able to silence it, and at worse, choose the course of action when an external link was encountered.

I used jQuery as the base library, but obviously it could be easily translated to another library or to library independence.

Stay on target… stay on target…

Having stalled long enough, and with no further ado, 40 lines of “anchor targeted window scripting” bliss (with attached line-by-line description):

(function(){
  var extAnchorTarget = function () {
    var msgtxt = null, usropt = null, askopt = null;
    msgtxt = "Click OK to open this link in a new window "
           + "or cancel to open it in this window.";
    usropt = $(":radio:checked[name=extwinopt]").val() || 0;
    usropt = parseInt(usropt);
    switch (usropt) {
      case 2:
        this.target = "_blank";
      break;
      case 1:
        this.target = "_self";
      break;
      case 0:
      default:
        askopt = confirm(msgtxt);
        this.target = !askopt ? "_self" : "_blank";
      break;
    }
    return true;
  };
  var labelAnchors = function () {
    var winhome = document.domain.split(".").reverse();
        winhome = winhome[1]+"."+winhome[0];
    $("a").each(function(i){
      var lnkhome = this.href.split("/")[2].split(".").reverse();
          lnkhome = lnkhome[1]+"."+lnkhome[0];
      if (!winhome.match(lnkhome)) {
        $(this).addClass("external");
        $(this).click(extAnchorTarget);
      } else {
        $(this).addClass("internal");
      }
    });
  };
  $(function(){
    labelAnchors();
  });
})();

If you’re using jQuery on your site already, just load this script and all of your target="_blank"-anchors-opening-in-new-windows dreams will come true.

Ultimately, this script would be integrated with two additional features:

  • Modals – At the moment, this script relies on the browser confirm function which is a bit ugly and klunky. A polished modal window that would appear as needed would make this the real deal.
  • Cookies – Having integrated a lovely modal widget, we should store the user’s preference to prevent our script from bugging them.

You’ll notice that on Line 6, the script is looking for a form value which contains the user options. While it will silently default to asking the user, this would ultimately be the place where we might also check for a cookie value.

The demo (written in shiny XHTML 1.1 Strict) includes a form which works, but which is obviously reset every time the page is loaded. This would be a problem for a website without a cookie solution, though it’s less apparent in the single page demo.

This script now has the potential to fill the requirements outlined above. It performs its own domain to href comparison, so I could throw it right into an application. I don’t have to set additional values on any attributes, though there’s probably some good reason I should be adding rel="external" to off-site links anyway. It contains a built-in mechanism for asking the user, rather than simply forcing the user to open a new window.

Demo/Download

For anyone who missed it, here is another link to the online demo:

View/download the external links demo »

Wrapping Up…

So there you have it. Now go forth and please The Great Validator and The Great Usurpers. Much thanks to Kevin Yank of SitePoint.com for his original article and to Jeff Starr of Perishable Press for hosting this one. Also, a huge thank you to all User Experience Experts and Advocates for unwittingly and unfairly playing the role of the villain in my little story. I hope you’ll forgive my having a little fun at your expense and not rush out to buy a Bill Brown voodoo doll.

Bill Brown
About the Author Bill is the creator of WebDevelopedia.com and is an active member of several discussion lists, including the CSS Discussion List. When not online, Bill can be found enjoying the company of his girlfriend, Jessica and their dog, Leica (she doesn’t have a web site).
Archives
18 responses
  1. Joel "Cheaters Guide" Gutierrez January 22, 2009 @ 9:52 am

    So with the blank target do we get penalized for having that when it comes down to Google and other search engines? I have just learned how to do some .php coding but not anything complicated…so all this other coding gets me a bit confused.

  2. Kyle Kinnaman January 22, 2009 @ 9:09 am

    This is awesome. I was using this:

    $(‘a:not([@href^=”/”])’).attr(‘target’, ‘_blank’);
    $(‘a[@href^=”#”]’).attr(‘target’, ‘_self’);

    Of course, that means all sitelinks needed to be relative and not absolute, but it works like a charm. This is much better for the long term.

  3. Another idea: assume you are visiting a website with wallpapers, select the resolution you want, then right click and “save target/link as”.

    with a greasemonkey script that does the “anchor menu” you can do the save much easier.

  4. @Kyle
    That’s a nice solution, too. Of course, there’s a plethora of options out there. SmashingMagazine has a nice demo posted as well. This was just a proof-of-concept solution I was playing with for a client. It needs more to be ready for production use.

    @Joel:
    As I understand it, Google ignores the JavaScript, so as Google sees it, there is no target=_blank set anywhere. Other issues tend to create larger problems. Your site, for example, doesn’t employ a valid data structure or semantic tagging. This is, of course, your choice to code it like that and it displays just fine, but since you’re not using header tags to identify key portions of your content, Google and other search engines might have a harder time ranking you.

  5. Nice writeup! I’ve read Smashing Magazine’s article on a similar topic some time ago but I didn’t give it much thought, until somebody pointed out that in fact for most search engines out there, all their links are opened in the same window – and I believe that this is the correct way. With tabbed browsing introduced to the web browsing culture within the past few years, users are given more freedom to choose whether they want to open up a new window, new tab or simply stay on the same page. I think leaving this decision up to the visitors is the best choice, since forcing links to be opened in new windows is a little absurd.

    I feel a little ashamed for using target=”_blank” for my external links sometimes, but that just comes so naturally over the years. From now on I shall leave it to the visitors instead :) thanks for the great writeup!

  6. Nice write up. Very interesting solution.

    However, using XHTML 1.0 Transitional as your DOCTYPE validates target=”_blank” just fine, and that what the DOCTYPE exists for.

    Developers and designers who are making the transition from HTML 4.01 to XHTML 1.0, should be encouraged to use the Transitional DOCTYPE.

    Although now we are heading into HTML5 and that DOCTYPE does validate the target attribute.

    … and I just realized that this post is from 2009 and it all makes sense now. :)

[ Comments are closed for this post ]