Opening links in new windows in xhtml strict

My last post explores in detail why you can’t rely on a title attribute to warn a user that a link opens in a new window, as you’re required to under checkpoint 10.1 of WCAG 1.0.

Here’s Gez Lemon‘s script that opens any link marked rel="external" and opens it in a new window without being invalid. He’s just too damn modest to post this himself.

It automatically adds “(opens in new window)” to any link text (not the title, as that wouldn’t be seen by keyboard-only users). If the link is an image, it adds the warning to the alt text.

You mark the links up like this: <a href="wherever.pdf" rel="external">lovely document</a> (note NO target="_blank") and the link will open in a new window and the link text will read “lovely document (opens in new window)” for all users (and perhaps give your content authors/ brand manager heart failure).


window.onload = externalLinks;

function externalLinks()
{
var objCurrent, objReplacement;

if (document.getElementsByTagName)
{
var objAnchors = document.getElementsByTagName(‘a’);
for (var iCounter=0; iCounter<objAnchors.length; iCounter++)
{
if (objAnchors[iCounter].getAttribute(‘href’) &&objAnchors[iCounter].getAttribute(‘rel’) == ‘external’)
{
objAnchors[iCounter].onclick = function(event){return launchWindow(this, event);}
objAnchors[iCounter].onkeypress = function(event){return launchWindow(this, event);}

if (document.replaceChild)
{
objCurrent = objAnchors[iCounter].firstChild;
if (objCurrent.nodeType == 3) // Text node
{
objReplacement = document.createTextNode(objCurrent.data + ‘ (opens in a new window)’);
objAnchors[iCounter].replaceChild(objReplacement, objCurrent);
}
else if (objCurrent.alt) // Current element is an image
{
objReplacement = objCurrent;
objReplacement.alt = objCurrent.alt + ‘ (opens in a new window)';
try
{
objAnchors[iCounter].replaceChild(objReplacement, objCurrent);
}
catch(e){}

}
}
}
}
}
}

function launchWindow(objAnchor, objEvent)
{
var iKeyCode;

if (objEvent && objEvent.type == ‘keypress’)
{
if (objEvent.keyCode)
iKeyCode = objEvent.keyCode;
else if (objEvent.which)
iKeyCode = objEvent.which;

if (iKeyCode != 13 && iKeyCode != 32)
return true;
}

return !window.open(objAnchor);
}


Thanks Gez!

7 Responses to “ Opening links in new windows in xhtml strict ”

Comment by Craig Snyder

This is interesting–but I guess I was assuming:

onclick=”window.open(this.href); return false”

Validates without the need for the javascript, and you can let readers know the link will open in a new window via the title tag.

I’d like to know your thoughts on this…

Comment by archetwist

There is na error in the script. Apostrophes are incorrect (at least Opera has a problem with it). There should be ‘ instead of ‘ and ’ I think.

Comment by Ron Johnson

Brilliant!! Thanks very much.

After changing all the apostrophes/quotes it worked a treat!

I also added the following line from the first post to add “(opens in new window)” to the title attribute as well. Why not!

objAnchors[iCounter].title = (objAnchors[iCounter].title != “”) ? objAnchors[iCounter].title+” (opens in a new window)” : “opens in a new window”;

PS. if anybody wants a working version of external.js(with my single line mod), take a copy from here;

http://www.cash4coursework.com/include/javascript/external.js

Comment by Jenny Pacheco

Does anybody know if there is a way to add sizing to this script, so that the new window opens to a particular size? Or would that be horribly inaccessible?

I ask because I make use of this function in some tutorials I have written, so that the ‘guide’ opens in a narrow window that sits alongside another window containing the database that one is being instructed how to use… a two window version of frames, if you will… But now I am moving my pages over to xhtml 1.1, and trying to make them as accessible as possible, and find that the ‘window.open’ function I was using is not accessible, as it won’t work when javascript is off. The text does tell the user that two windows will open, but is having two windows side by side accessible?

Thanks for any help you can provide.