target='_blank' doesn't validate
Many web developers work hard to make sure web pages pass the W3C's HTML validation test. But site owners often ask for links to outside, or external, websites to open in a new window. (Site owners are afraid, apparently, that once a visitor leaves a site they will never come back!)
The easiest way to accomplish opening a page in a new window (or tab), which all major browsers support, is to use the target
attribute of the anchor element:
<a href='http://osric.net/' target='_blank'>osric.net web hosting</a>
This is such a common practice that you might ask, why is it not included in the HTML specification? I don't know the answer to that, but I would guess that the HTML specification allows for browsers (or user agents) that cannot spawn a new window, such as the text-based Lynx browser. Also, usability experts recommend against opening links in new windows because it breaks the back button, and users can easily open a link in a new browser window or tab if they choose.
Javascript Solutions using window.open()
There are a few ways we can open the link in a new window that will validate, which involve using window.open()
Using the onclick attribute
<a href='http://osric.net/' onclick='window.open("http://osric.net");return false;'>osric.net web hosting</a>
- Good example using the onclick attribute
- osric.net web hosting (opens in a new window)
Now the URL is listed in 2 places, and that's never a good thing. Referencing this.href
will allow us to keep in just one place:
<a href='http://osric.net/' onclick='window.open(this.href);return false;'>osric.net web hosting</a>
- Better example using the onclick attribute
- osric.net web hosting (opens in a new window)
This is good, but there is a possibility that a user will have his or her browser security settings such that all pop-ups, which includes windows opened with window.open()
, will be blocked even if the action is initiated by the user. window.open()
returns a Boolean value indicating the failure or success of the window opening.
<a href='http://osric.net/' onclick='return !window.open(this.href);'>osric.net web hosting</a>
If the window opens, the expression evaluates as, and returns, false
. If it fails to open, the expression evaluates as, and returns, true
--meaning that the link opens normally (but in the same window).
- Best example using the onclick attribute
- osric.net web hosting (opens in a new window)
What is this?
A note about this.href
and this
: although this.href
works in the above examples, and would work below in most browsers, Internet Explorer returns undefined
for this.href
in the examples below.
When using the onlick
attribute, this
referred to the anchor element, of which href
was a property. When assigning a function to the onclick object property, this
is the href value. I don't know why and haven't yet run across any explanations.
One thing to note in either case is that the URLs are absolute: <a href='/chris/accidental-developer/'>Accidental Developer</a>
returns a value of http://osric.com/chris/accidental-developer
for this.href
(or this
) on this server.
Using the onclick object property
Some developers prefer to avoid using the onclick
attribute within a tag, and prefer to assign an onclick property to the DOM object programmatically. (This could have the unintended consequence of overriding a previously applied onclick property, or overring an inline onclick
attribute.) Here are a couple examples:
Using a CSS class name to identify outside links and attach the event handler
I prefer this method. Anyone looking at the code can see that the link is marked "external," and a CSS style could be used to insert an external link identifier (as below).
<style type='text/css'> .external { background-image:url(/chris/images/external-link.png); background-position:right center; background-repeat:no-repeat; padding-right:14px; } </style> <a href='http://osric.net/' class='external'>osric.net web hosting</a> <script type='text/javascript'> // Get all the anchors in the entire document // (You can also use document.links to get the links) var anchors = document.getElementsByTagName('a'); // Loop through the anchors and add the click handler if it includes the CSS class 'external' for ( var i in anchors ) if ( anchors[i].className && anchors[i].className.indexOf('external') != -1 ) anchors[i].onclick = function () { return !window.open(this); }; </script>
- Example assigning onclick property by class name
-
- osric.net web hosting (opens in a new window)
- The Accidental Developer
Detecting external links and assigning the onclick property programmatically
The following example checks to see if the site domain name is part of the destination URL. If not, it sets the link to open in a new window. Something like this could be applied to an existing site without searching through the code to identify external links, although it could potentially mis-identify an external link as internal (e.g. http://www.google.com/search?q=osric.com
contains the site domain name).
<a href='http://osric.net/'>osric.net web hosting</a> <script type='text/javascript'> // Get all the anchors in the entire document, or in this case, a subset of the document // use document.getElementsByTagName('a') or document.links to get all anchors var anchors = document.getElementById('externalLinks').getElementsByTagName('a'); // Loop through the anchors and add the click handler if it includes the CSS class 'external' for ( var i in anchors ) // Look for our domain, e.g. osric.com, and add a click handler if we don't find it if ( anchors[i].href && anchors[i].href.indexOf('osric.com') == -1 ) anchors[i].onclick = function () { return !window.open(this); }; </script>
- Example detecting external links and assigning the onclick property
-
- osric.net web hosting (opens in a new window)
- The Accidental Developer
Attaching an Event Handler
Internet Explorer uses object.attachEvent()
, but not object.addEventListener()
. Firefox (and others) use object.addEventListener()
, but not object.attachEvent()
. In the case of Internet Explorer, the this
context is not passed to the handler function, making it trickier to access information about the object upon which the user acted. O'Reilly's Dynamic HTML, 2nd Edition recommends against attaching the event handlers, saying that "Tag attribute and object property assignment are the two event binding techniques that work best across all browsers." QuirksMode.org also has interesting info on this subject; see Advanced Event Registration Models for details.
If you use a Javascript framework such as jQuery, you can use their methods of attaching event handlers--the frameworks see to cross-browser compatibility. Check out jQuery's click() method. Attaching event handlers does have a distinct advantage: an object can have mutiple event handlers (including for the same event, e.g. multiple click handlers), so assigning a click handler to open a link in a new window would not necessarily interfere with any other click handlers (or onclick
attributes) that the object may have.
<ul> <li><a href='http://osric.net/' class='external'>osric.net web hosting</a> (opens in a new window)</li> <li><a href='/chris/accidental-developer/'>The Accidental Developer</a></li> </ul> <script type='text/javascript' src='/chris/javascript/jquery-1.4.3.min.js'></script> <script type='text/javascript'> $('#jqueryExamples').find('a.external').click( function() { return !window.open(this); }); </script>
- Examples using jQuery
-
- osric.net web hosting (opens in a new window)
- The Accidental Developer
Questions? Comments? Leave a message for me on the associated blog post: Opening links in a new window without the target attribute