Categories
href html javascript optimization performance

Which “href” value should I use for JavaScript links, “#” or “javascript:void(0)”?

4336

The following are two methods of building a link that has the sole purpose of running JavaScript code. Which is better, in terms of functionality, page load speed, validation purposes, etc.?

function myJsFunc() {
    alert("myJsFunc");
}
<a href="#" onclick="myJsFunc();">Run JavaScript Code</a>

or

function myJsFunc() {
    alert("myJsFunc");
}
 <a href="https://stackoverflow.com/questions/134845/javascript:void(0)" onclick="myJsFunc();">Run JavaScript Code</a>

1

  • 6

    Why use a link when you want a button? Then there is no issue with pseudo–protocols.

    – RobG

    Jun 11 at 12:57

1396

+100

Neither.

If you can have an actual URL that makes sense use that as the HREF. The onclick won’t fire if someone middle-clicks on your link to open a new tab or if they have JavaScript disabled.

If that is not possible, then you should at least inject the anchor tag into the document with JavaScript and the appropriate click event handlers.

I realize this isn’t always possible, but in my opinion it should be striven for in developing any public website.

Check out Unobtrusive JavaScript and Progressive enhancement (both Wikipedia).

3

  • 36

    “If that is not possible, then” use a button instead. That’s how this answer should’ve ended.

    May 29, 2021 at 0:52


  • and if we use a button, how would our lovely users will open their href in new tab using their shiny smartphones?

    Feb 11 at 4:57

  • 1

    @mohamedtebry—you’ve missed the point of the question: “building a link that has the sole purpose of running JavaScript code“. The issue is using a link as a button, there is no href to open.

    – RobG

    Jun 11 at 12:59

801

Doing <a href="#" onclick="myJsFunc();">Link</a> or <a href="https://stackoverflow.com/questions/134845/javascript:void(0)" onclick="myJsFunc();">Link</a> or whatever else that contains an onclick attribute – was okay back five years ago, though now it can be a bad practice. Here’s why:

  1. It promotes the practice of obtrusive JavaScript – which has turned out to be difficult to maintain and difficult to scale. More on this in Unobtrusive JavaScript.

  2. You’re spending your time writing incredibly overly verbose code – which has very little (if any) benefit to your codebase.

  3. There are now better, easier, and more maintainable and scalable ways of accomplishing the desired result.

The unobtrusive JavaScript way

Just don’t have a href attribute at all! Any good CSS reset would take care of the missing default cursor style, so that is a non-issue. Then attach your JavaScript functionality using graceful and unobtrusive best practices – which are more maintainable as your JavaScript logic stays in JavaScript, instead of in your markup – which is essential when you start developing large scale JavaScript applications which require your logic to be split up into blackboxed components and templates. More on this in Large-scale JavaScript Application Architecture

Simple code example

// Cancel click event
$('.cancel-action').click(function(){
    alert('Cancel action occurs!');
});

// Hover shim for Internet Explorer 6 and Internet Explorer 7.
$(document.body).on('hover','a',function(){
    $(this).toggleClass('hover');
});
a { cursor: pointer; color: blue; }
a:hover,a.hover { text-decoration: underline; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="cancel-action">Cancel this action</a>

A blackboxed Backbone.js example

For a scalable, blackboxed, Backbone.js component example – see this working jsfiddle example here. Notice how we utilize unobtrusive JavaScript practices, and in a tiny amount of code have a component that can be repeated across the page multiple times without side-effects or conflicts between the different component instances. Amazing!

Notes

  • Omitting the href attribute on the a element will cause the element to not be accessible using tab key navigation. If you wish for those elements to be accessible via the tab key, you can set the tabindex attribute, or use button elements instead. You can easily style button elements to look like normal links as mentioned in Tracker1’s answer.

  • Omitting the href attribute on the a element will cause Internet Explorer 6 and Internet Explorer 7 to not take on the a:hover styling, which is why we have added a simple JavaScript shim to accomplish this via a.hover instead. Which is perfectly okay, as if you don’t have a href attribute and no graceful degradation then your link won’t work anyway – and you’ll have bigger issues to worry about.

  • If you want your action to still work with JavaScript disabled, then using an a element with a href attribute that goes to some URL that will perform the action manually instead of via an Ajax request or whatever should be the way to go. If you are doing this, then you want to ensure you do an event.preventDefault() on your click call to make sure when the button is clicked it does not follow the link. This option is called graceful degradation.

1

  • Good answer, but it would be better if the jQuery dependency is removed. 😉

    – RobG

    Jun 11 at 13:03