Links, the onclick attribute, and page accessibility
Under this slightly unfortunate heading I’ll show how to handle opening
a new window properly with client-side scripting. To put it in context, I mean cases where
you can’t use the target attribute, which isn’t allowed in
XHTML, for example.
Sometimes you need a link to open a new window. There are several reasons for doing so, and this
post is no defense of either side of the debate. My aim is to show how to register and handle
a link’s onclick event properly. You’ll usually see it written like this.
<a href="foo.html" title="popis odkazu" onclick="bar(this.href);return false;" hreflang="cz" lang="cz" xml:lang="cz">The example above is the one commonly recommended. Let’s recap the important bits.
We registered a handler for onclick in the bar function, passing it the contents
of href as an argument, then returned false.
What happens when you click a link
When you click the link, control goes first to the registered event handler, which opens a new window.
After it runs, false is returned. That prevents the browser from following
the actual href. If someone has client-side scripting disabled or limited, the browser follows
href itself and skips the onclick handler.
Trouble on the horizon
It looks like we’ve covered everything. With client-side scripting disabled or limited, users get
the usual href behavior. But appearances are deceptive. We forgot about cases where a new
window can’t open or opening it fails. That might happen because of a pop-up blocker,
a browser-instance limiter, a failed script, or a browser on an alternative device that doesn’t support new windows at all.
If any of those things happens, the event handler runs but the requested page doesn’t
open in the new window, so the user can’t access the page the link points to. The handler is followed
immediately by a return of false, which prevents href from being followed even though in that
case we would want it to be.
Possible solutions
It may not look that way at first, but the solution is close to the original. When opening a new window,
test the result. If the window was created and the reference is valid, there’s no need to follow href. If
there’s trouble, return true to let the browser follow href.
The example looks like this.
<a href="foo.html" title="popis odkazu" onclick="return !bar(this.href);" hreflang="cz" lang="cz" xml:lang="cz" >
<script type="text/javascript" >
.
.
.
function bar(url){
wasOpen = false;
win = window.open(url);
return (typeof(win)=='object')?true:false;
}
We stored the reference to the new window in win, then
tested it. If the window opened, the function returns true.
The handler negates that to return false, preventing href from being followed.
If the window didn’t open, the function returns false and the browser follows
href as a result.
For a more reliable test, you could check the URL of the newly opened window, for instance, rather than
relying only on the data type. In fairness to browsers such as Mozilla 1.0 and
Internet Explorer, if the client-side script fails internally they follow href as usual.
Medium version · Archived original page
Related articles
Related CZ Podcast episodes
- #217 · Ivo Lukačovič
On Windy, JavaScript and building companies. · Czech audio
- #3 · Java 6 SE, Vývoj webových aplikací
Dagi and Filemon discuss Java 6 and web application frameworks. · Czech audio