blog

Photo of cardboard hashtag symbol by Jan Baborák on Unsplash

Anchors, Hash Sign, javascript:void(0)

by

So, you’ve got a link that, in reality, is just a click target for performing some javascript function. You want the appearance of a standard anchor link, but if it’s not performing the intended function, should it really be an anchor? And if so, what should we fill that ‘href’ attribute in with?

Let’s begin with a nasty anti-pattern:

<a onclick="alert('Obtrusive!'); return false;">Click Me</a>

Boo, hiss!

Why is this so bad?

First, the onclick handler is a clear violation of unobtrusive javascript. The wikipedia article covers in reasonable detail why using this sort of handler is highly discouraged, but in a nutshell, behaviour and structure should be as separate as structure and presentation (ie. html and css).

Secondly, the lack of href attribute would normally indicate this is an anchor element (as opposed to a link) – functionally speaking, it should have an id which corresponds to a href="#id" somewhere on the page. It probably won’t break anything (unless you have code or styling that’s looking for said attribute), but it won’t gain the pointer cursor when you hover over it, and it shoehorns the element into performing a function it was never really intended for.

This isn’t really any better:

<a onclick="jsfunc();">Click Me</a>
function jsfunc(){
    alert('Still obtrusive');
    return false;
}

We still have the obtrusive onclick handler – the fact that we’ve shoved the logic into a function doesn’t really improve the situation.

Here’s a better example:

<a id="click_target" href="#">Click Me</a>

We’ve added an id to the anchor, along with a simple hash in the href. Now, the mouse will gain the expected pointer cursor on hover, and we can look up the element by its id and attach behaviours to it unobtrusively.

However, we now have a href that doesn’t really point anywhere. If something goes wrong – javascript is disabled, fails to init due to an error, etc. – clicking it will take us back to the top of the page and alter the url. This isn’t generally terrible, but it’s certainly not desirable either. And what if we’re using hash fragements for maintaining state, or routing (such as in Backbone)? Changing the hash could be problematic.

Moreover, we now need to cancel the default action in our javascript. We could return false;, but this is a misuse of the return, which should offer a value to other calling functions, not be used to cancel actions. We can, of course, preventDefault() on the event, and this is the best way to handle this situation, but maybe we want to avoid having to handle a default action altogether?

A common solution looks like:

<a id="click_target" href="javascript:void(0);">Click Me</a>

Personally, I don’t really like this solution, or its cousin href="javascript:;" but it does work well. We now have a click target that will present itself in the expected way, and perform no default action we need to cancel. But use of the javascript psuedo-protocol is a bit messy – it looks a lot less neat than the simple hash.

Maybe the best solution, then, is not to use a link at all. A button element can be styled to look and function like a link, and performing an arbitrary behaviour is really what a button is all about.

As an aside, void – even if I don’t recommend using it this way – is extremely handy, as its guaranteed to return undefined. void 0, void(0), void ‘whatever’, will all return undefined. This is a great way to avoid testing against the mutable undefined global variable, or needing to use the longer typeof variable == 'undefined'.

Consider this:

<button id="click_target" type="button" tabindex="0" class="link_alike">Click Me</button>
.link_alike{
    background:transparent;
    border-color:transparent;
    border-radius:0;
    color:#0088CC;
    cursor:pointer;
}
.link_alike:hover{
    text-decoration:underline;
    color:#005580;
}

You’ll likely want to add :focus and :active states as well, but the above gives you the basics of a click target with no default behaviour beyond looking and acting like a link – perfect for attaching your javascript to while still presenting your user with a familiar target.

Now, I won’t claim this is my goto solution – I tend to use link’s with a simple hash and just cancel the default action. There are some advantages to this approach – the markup is a bit simpler, tabbing via the keyboard is supported without the ‘tabindex’ attribute, and no additional styling is needed.

On consideration, though, maybe I’ve developed a bad habit in doing so – perhaps one that needs to be replaced with a button-based solution. What do you think?

+ more

Accurate Timing

Accurate Timing

In many tasks we need to do something at given intervals of time. The most obvious ways may not give you the best results. Time? Meh. The most basic tasks that don't have what you might call CPU-scale time requirements can be handled with the usual language and...

read more