written on:7 Feb, 2008 by Alen Grakalic

Open External Links in New Window Automatically

Delicious StumbleUpon Reddit Subscribe

search

What I have here is a JavaScript experiment that might be useful.
As we already know, target attribute for anchor tags in strict doctypes is not included. But we also know that sometimes we want to open a page in another window.
If we're talking about all external pages, I might have a solution that you can easily apply even to your old sites.

This script initiates on page load and goes through all links (anchor tags) in the document. It then checks links, and based on current domain name it recognizes them as internal or external. Furthermore, the script adds a class name "external" to all external links. That way you can visually separate them from internal links. The greatest thing about it is that it doesn't demand any markup interventions so you can use them on previous projects by simply plugging in the JavaScript function.

Take a look at the demo | Download Blankwin script

Here's the script. It can't get any simpler.

The script initiates on page load

this.blankwin = function(){
	var hostname = window.location.hostname;
	hostname = hostname.replace("www.","").toLowerCase();
	var a = document.getElementsByTagName("a");	
	this.check = function(obj){
		var href = obj.href.toLowerCase();
		return (href.indexOf("http://")!=-1 && href.indexOf(hostname)==-1) ? true : false;				
	};
	this.set = function(obj){
		obj.target = "_blank";
		obj.className = "external";
	};	
	for (var i=0;i<a.length;i++){
		if(check(a[i])) set(a[i]);
	};		
};

About the author

cssglobe's image

Designer, developer and a passionate standardista. Long time web professional with huge experience in all types of front-end work. Founder of Css Globe and creator of Easy front-end framework.
To get in touch, visit Alen's personal page, follow Alen on Twitter or become a Facebook friend.

Enjoyed the article?

Then don't miss our next one! Subscribe to our RSS feed or share it with your friends.

Delicious StumbleUpon Reddit Subscribe

Read more! Here are our most recent articles:

View All Articles

Comments

  1. Karl Steltenpohl 7 Feb, 2008

    I like. Maybe Ill find a use.
  2. Jeremy Hicks 7 Feb, 2008

    Good trick, I've already added it to my arsenal.

    Maybe I don't understand Strict Validation so much, but this script is essentially adding the target="_blank". Is the markup still considered 'strict' once that has been injected?

    And for existing sites, some css backporting might be necessary if you've already styled the links, unless I'm not understanding something.
  3. mginop 7 Feb, 2008

    This is great, thanks. I assume if you add class="external" to an internal file (eg: PDF file), it will open in a new tab too?
  4. Davewood 7 Feb, 2008

    Isn't this solution cheating the purpose of using strict validation? The idea behind removing the target attribute in the strict doctype is to allow the user to decide when they want to open a new tab/window.

    Rather than using strict validation and this "workaround", why not be truthful and validate it as transitional and use the target attribute.

  5. John 7 Feb, 2008

    Looks promising. Will give this a go.
  6. cssglobe 7 Feb, 2008

    Well, Davewood you are partially correct. Primarily the idea is to warn user about new window, to let him know that this is going to happen and avoid confusion. On some screen readers there are no telling that this has happened. Those readers generally don't support JavaScript, so there's no harm done with unotrusive JS.
    Btw, even in the working draft for Techniques for WCAG 2.0 there is a <a href="http://www.w3.org/TR/WCAG20-TECHS/SCR24.html">sample function</a>
  7. cssglobe 7 Feb, 2008

    On the other note, should we use script to maintain valid code and have page behave "invalid"... That is a really good question. Similar thing happen with including source code for flash. Basically what you do is insert invalid code. But, with unobtrusive JavaScript you at least filter some potential problems out.
    This script is merely a demonstration, it gives developers a choice of using new windows for all external links if they want to.
  8. CSSnewbie 7 Feb, 2008

    This would also be a useful script to run on non-strict documents, assuming you wanted a quick and easy way to change all of your external links to load in a new window. I like the idea of not having to remember to set the target on every single external link, if this is the behavior I wanted. Good stuff!
  9. Paul Sayre 7 Feb, 2008

    I'd have to agree with Davewood. This kinda seems like a trick to get around strict dtd. At first glance, this seems like a really good idea simply because most developers want this action.

    But from a user stand point, I want full control over what is opened in what browser window and when. As a user, I would rather see a link of different color or see an icon rather then have my actions dictated by a developer.

    That said, I really like the script. If you have chosen to get around strict and keep the functionality, this is a great way to do it. Keep up the good work, Alen!
  10. cssglobe 7 Feb, 2008

    The one way we can all be happy is to include "open external links in new window" option somewhere on the site when using this script.
    This script is merely the tool, we should find the way to use it in a good way...
    Cssnewbie noticed it well, the of the script "strength" is in its applicability. You can simply drop it on the document and it will work, no interventions in the code needed. How will you deliver that option to users is up to you.
  11. kenman 8 Feb, 2008

    A couple notes...

    1) Instead of attaching the script to the global JS object, it'd be better served wrapped in an anonymous structure so as to avoid global namespace collisions.

    2) All modern browsers I believe support the lvl 1 DOM "links" collection, which I would presume would be considerably faster than getElementsByTagName().

    3) You don't need all those this's.

    4) The script WON'T "initiate on page load". It merely gets defined. You'd have to manually call blankwin(), and only sometime after the DOM is loaded.

    My take:

    (function(){
    var hostname = window.location.hostname.replace("www.", "").toLowerCase();
    var i = document.links.length;
    while ( --i >= 0 ) {
    var thisLink = document.links[i];
    var thisHref = thisLink.href.toLowerCase();
    if ( thisHref.indexOf("http://") != -1
    && thisHref.indexOf(hostname) == -1 )
    {
    thisLink.target = '_blank';
    thisLink.className = 'external';
    }
    }
    })();
  12. kenman 8 Feb, 2008

    I see now in your demo you have an additional function not shown above, addEvent(). To be clear, the snippet I posted above would only work if place at the bottom of the page, which of course isn't always desirable.

    I would still highly recommend using document.links.length though if your page is anything other than simple.
  13. cssglobe 8 Feb, 2008

    Thanks for sharing that, kenman.
  14. Mike 8 Feb, 2008

    Wasn't this originally posted in 2003 by Kevin Yank? Reason I know is because I just researched this for a couple hours the other day.

    http://www.sitepoint.com/article/standards-compliant-world
  15. cssglobe 8 Feb, 2008

    @Mike: there are lots of examples like Kevin's. The difference between his example and mine is that my script does this <strong>automatically</strong>.
    It examines the value of the href attribute, compares is to current domain name, and if the domain name is different, it marks link as external. Plus, my script adds a class name on external links, something Kevin's script doesn't do at all. That class name can be used to visually separate external links.
    Downside to Kevin's script is that you have to manually add rel="external" to each anchor tag you want to open in new window. Downside to mine is that you can't separate some external links from others.
  16. Mike 8 Feb, 2008

    Ahh..I see. I kind of like the upside's of both. Thank you for clarifying!
  17. naveed 12 Feb, 2008

    wow...this is great. I will must use this in my project. I love this! thanks
  18. Vincenzo 15 Feb, 2008

    Thanks for wonderful script. This i a good idea to show to users what link are external and also what link will be opened in a new window.
  19. track40 18 Feb, 2008

    Looks like a nice script...

    This seems to work for me, and validates with XHTML Strict:

    <a href="http://www.yourdomain.com" onclick="window.open(this.href,'newwin'); return false;">http://www.yourdomain.com</a>

    Insert the: onclick="window.open(this.href,'newwin'); return false;" into your <a href>, and the link when clicked will spawn a new window.
  20. Vitaly 19 Feb, 2008

    Nice idea! Thanks.
    Bad for SEO :(
  21. noth 21 Feb, 2008

    Hola, perdón por no hablar en ingles.

    Yo tengo creado un plugin para jquery que hace eso mismo, y además una serie de funcionalidades más , lo podeís probar y descargar en http://www.noth.es/2007/11/24/actualizacion-del-jquery-link-version-03/

    Demo
    http://www.noth.es/jquery/mis_plugins/jqueryLinks-0-3-by-noth/

    Saludos
  22. Faisal 25 Feb, 2008

    i tested the script, it works fine.

    but i have a question, with AdSense ads, will it open in a new window?

    i actually don't want the AdSense ads to open in a new window, because its against google TOS.

    i couldn't test it, because i dont want to click my own ads.

    thanks
  23. chad 29 Feb, 2008

    Nice idea..but for SEO purposes what about "nofollow"? Or does this work with it as well?
  24. Miller Medeiros 15 Apr, 2008

    very handy script.. the only things i suggest is using [ document.anchors.length ] instead of [ document.getElementsByTagName("a"); ]

    also instead of just setting the className to "external" you should append it.. because if some external link already have a class it will be replaced after the script runs.. it should be [ obj.className += " external"; ]

    i also suggest compressing the javascript and put in the zip file a compressed JS and an uncompressed file (source)..

    thanks for sharing your knowledge with the community, your blog have some very nice tips.. keep your good work..

    cheers..
  25. Martin 16 Apr, 2008

    I think this should be an option in the browser (for those people too lazy to move the finger from the left to the middle button).
  26. salvia 6 Jun, 2008

    Would this work on flash embeded content like youtube?
  27. Salvia 10 Jun, 2008

    Very nice code.

    It's suprising the number of people who still think the target attribute of the anchor tag is valid xhtml. :)
  28. Katrine Roof (Watson) 14 Jun, 2008

    Thanks for really working script.
    It's a good idea to show to user when links are external and when they will be opened in a new windows.
  29. Volfgang Stropila 14 Jun, 2008

    Yes, idea is good. But it's not good SEO-optimisation and Search Engines, who can index these links.
  30. Nick Stars 9 Jul, 2008

    Thanks! I will use this in my project.
  31. Stephan Kockmann 19 Jul, 2008

    Hi Alen,
    thank you for the great script!

    @Faisal: If you do not want to open AdSense-Links in a new window, you can treat them like an internal link by changing this line of code:

    return (href.indexOf("http://")!=-1 && href.indexOf(hostname)==-1) ? true : false;

    to this:

    return (href.indexOf("http://")!=-1 && href.indexOf(hostname)==-1 && href.indexOf("googlesyndication.com")==-1) ? true : false;

    If you have further links you do not want to open in a new window, you can add them like this:

    return (href.indexOf("http://")!=-1 && href.indexOf(hostname)==-1 && href.indexOf("googlesyndication.com")==-1 && href.indexOf("...")==-1) ? true : false;

    Just replace the "..." by a unique part of domain-name for the links to exclude.

    Maybe there is even a better way to solve this "problem"? Suggestions are welcome!

    Stephan
  32. redking 26 Jul, 2008

    hi
    how about opening external links in a predefined frame ? where all external links opens in a frame page,(2 frames) where top flame informs that the visitor is on the external site & bottom frame is the external site.

    looking forward...
  33. Clayton Narcis 5 Aug, 2008

    Great script man.
  34. anoop 6 Aug, 2008

    First of all thanks for sharing this nice utility.
    It works for most of the things except Google adsense area and ajax based RSS feed section. Could you provide necessary code to make it fit also for ajax based RSS feed block?

    thanks very much in advance.
  35. C. Sundsdal 8 Aug, 2008

    This script is pure magic.... because it works :)

    thanks x 10
  36. Louis Lazaris 18 Aug, 2008

    The sitepoint article that originally gave the rel="external" code for strict DTDs explains that it is not considered "cheating". Here's what it says:

    "Sure, the page will validate against the HTML 4.0 Strict and XHTML 1.0 Strict Document Type Definitions, but aren't we technically cheating?

    The answer is no. The Document Object Model (DOM), which governs the document objects and attributes that are available to JavaScript code, is a totally separate standard from (X)HTML. Also consider that the DOM 2.0 standard that was published in January 2003 (well after XHTML 1.0, let alone HTML 4.0) still includes this attribute. It seems clear that while this attribute is slated to be phased out of (X)HTML, it will be available to JavaScript through the DOM for the foreseeable future."
  37. Moses Adrien 17 Dec, 2008

    Alternatively, you can use jquery to do this:
    $(document).ready(function(){
    $('#content_area_middle a[href^="http://"]').addClass('external').attr("target", "_blank");
    $('#content_area_middle a[href^="https://"]').addClass('external').attr("target", "_blank");
    });
  38. Jacob Halton 21 Dec, 2008

    Hmm....this looks like the kind of function I've been looking for...I think.

    I need a code that can work like a class, where I just apply it to a link and it'll open in a new window, without creating a function for each link, there will be over 50 of them...

    Is this something that can do that? I'm really new at javascript so I don't know if I'm using this thing right, it looks like it's supposed to make ALL the A tags popup, but it's not working when I use it.

    Anybody want to help? email: jhaltondesign@hotmail.com
  39. tarun kumar 24 Dec, 2008

    thanx that is exactly what i m looking for.
  40. Dangerell 11 Jan, 2009

    Script works great. Thank you, just what i needed!
  41. Poppoll 20 Feb, 2009

    What if the external link is an image?
    I don't want the icon in this case.
  42. Steve 25 Feb, 2009

    Any ideas how I would use this script with an iframe that is loading alien content... eg, our server is updated daily with a bunch of govermnt html files... we call these into our site using an iframe and style them with css so that they fit in... however the html files which are displayed sometimes contain links to sites outside of our domain / server and we would like these to be opened in a new window and not in the iframe.

    I have tried... using this script in the parent file, but it doesn't affect the iframe content... and I cannot include it in the html files shown in the iframe as these are updated each day.

    Any ideas?

    thanks
    s
  43. Bob 2 Apr, 2009

    This script works very well, but I was curious as to how to edit it to include all links to PDF files, whether they are local or external.
    Thanks!
  44. Richard Phung 24 Apr, 2009

    Great script..
    wow.. thank you so much.
  45. Brian 19 Jun, 2009

    This is perfect for my blogs. Thanks!

Sorry, further comments are disabled for this post.

CSS Globe is a web design magazine brought to you by Alen Grakalic and kept fresh with member contributed news and exlusive articles.

CSSG Ads

Useful Links

Friends