views:

45228

answers:

29

When building a link that has the sole purpose to run javascript, is it better to:

<a href="#" onclick="myJsFunc();">Link</a>

Or

<a href="javascript:void(0)" onclick="myJsFunc();">Link</a>
+4  A: 

'#' will take the user back to the top of the page, so I usually go with void(0).

Adam Tuttle
The way to avoid that is to return false in the onclick event handler.
Guvante
Returning false in the event handler doesn't avoid that if JavaScript the JS doesn't run successfully.
David Dorward
using "#someNonExistantAnchorName" works well because it has nowhere to jump to.
scunliffe
+1 only true direct answer to the question
Joe Hopfgartner
+1  A: 

I just the javascript:void(0) but in your onclick event try to end it with return false;

stephenbayer
Why do you end it with return false?
Thomas Owens
+25  A: 

The first one, ideally with a real link to follow in case the user has JavaScript disabled. Just make sure to return false to prevent the click event from firing if the JavaScript executes.

<a href="#" onclick="myJsFunc(); return false;">Link</a>
Zach
So in user agents with JavaScript enabled and the function supported this run a JavaScript function, falling back (for user agents where the JS fails for whatever reason) to a link to the top of the page? This is rarely a sensible fallback.
David Dorward
"ideally with a real link to follow in case the user has JavaScript disabled", it should be going to a useful page not #, even if it's just an explanation that the site needs JS to work. as for failing, I would expect the developer to use proper browser feature detection, etc before deploying.
Zach
I would assume (hope) that something like this would only be for showing a popup or something similarly simple. In that case, the default would be the popup page url. If this is part of a web application, or having JS disabled would totally break the page, then this code has other issues...
bmoeskau
My web apps are designed to degrade gracefully, so the link will still be a useful page. Unless your web app is a chat client or something that interactive, this should work if you put in the time to design with degradation in mind.
Zach
A: 

Don't lose sight of the fact that your URL may be necessary -- onclick is fired before the reference is followed, so sometimes you will need to process something clientside before navigating off the page.

nathaniel
+8  A: 

Unless you're writing out the link using JavaScript (so that you know it's enabled in the browser), you should ideally be providing a proper link for people who are browsing with JavaScript disabled and then prevent the default action of the link in your onclick event handler. This way those with JavaScript enabled will run the function and those with JavaScript disabled will jump to an appropriate page (or location within the same page) rather than just clicking on the link and having nothing happen.

Simon Forrest
+90  A: 

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: http://en.wikipedia.org/wiki/Unobtrusive_JavaScript

and

http://en.wikipedia.org/wiki/Progressive_enhancement

Aaron Wagner
What happens if you don't have a URL that makes sense?
AnthonyWJones
What if you aren't developing a website for public access?
AnthonyWJones
Hence my statement "I realize this isn't always possible".On a URL that makes sense, I'd say you should strive to have a non-javascript downgrade option for whatever the javascript link will provide.On second thought, even non-public sites should strive to follow progressive enhancement.
Aaron Wagner
Correction: onclick does fire for middle clicks, at least in some browsers. Haven't done testing to know which browsers do what, but I have to specifically exclude it on Safari, at least.
eyelidlessness
If you don't have a URL that makes sense I'd question putting the link into the HTML in the first place. If it's purely to fire off a JavaScript function, why not add the link in unobtrusively via JavaScript?
Jason Berry
href="javascript:" or href="javascript:void()" but definitely not a link if it doesn't exist (on a public site), Google won't be happy in the sitemaster tools. And definitely not href="#" as for drop down menus that move the scrollbar, it jumps back up when you click.
Chris S
+1 for middle click.
Sean McMillan
At the *absolute* worst (and there should always be a better way than this), you should link to an information page (/help.html#javascript-links) which explains that, for whatever reason, you're restricting that link to only people who have javascript enabled.
Bobby Jack
+10  A: 

Ideally you'd do this:

<a href="javascriptlessDestination.html" onclick="myJSFunc(); return false;">Link text</a>

Or, even better, you'd have the default action link in the HTML, and you'd add the onclick event to the element unobtrusively via JS after the DOM renders, thus ensuring that if JavaScript is not present/utilized that you don't have useless event handlers riddling your code and potentially obfuscating (or at least distracting from) your actual content.

Steve Paulo
+1  A: 

It's nice to have your site be accessible by users with javascript disabled, in which case the href points to a page that performs the same action as the javascript being executed. Otherwise I use "#" with a "return false;" to prevent the default action (scroll to top of the page) as others have mentioned.

Googling for "javascript:void(0)" provides a lot of information on this topic. Some of them, like this one mention reasons to NOT use void(0).

mmacaulay
The blog entry does not cite the reference as to why javascript:void(0) should be avoided.
AnthonyWJones
A: 

Ideally you should have a real URL as fallback for non-JavaScript users.

If this doesn't make sense, use # as the href attribute. I don't like using the onclick attribute since it embeds JavaScript directly in the HTML. A better idea would be to use an external JS file and then add the event handler to that link. You can then prevent the default event so that the URL doesn't change to append the # after the user clicks it.

Peter
+13  A: 

Neither if you ask me;

If your "link" has the sole purpose of running some javascript it doesn't qualify as a link; rather a piece of text with a javascript function coupled to it. I would recommend to use a <span> tag with an onclick handler attached to it and some basic CSS to immitate a link. Links are made for navigation, and if your javascript isn't for navigation it should not be an <a> tag.

Example:


<style type="text/css">
.jsAction {
    cursor: pointer;
    color: #00f;
    text-decoration: underline;
} 
</style>

<p>I wanna call a JS function <span class="jsAction" onclick="callFunction();">here</span></p>
D4V360
This approach restricts the 'link' to a mouse only operation. An anchor can be visited via the keyboard and its 'onclick' event is fired when the enter key is pressed.
AnthonyWJones
Hardcoding colors in your CSS would prevent the browser from using custom colors the user may define, which can be a problem with accessibility.
Hosam Aly
They boil down to the same thing it's semantics to use a span or an anchor tag. If the page url can only be generated in javascript it makes no difference where it's running from apart from as pointed out anchor tags can use keyboard navigation.
PeteT
Quite cumbersome. A link would have solved the problem too.
usr
+2  A: 

Depending on what you want to accomplish, you could forget the onclick and just use the href:

<a href="javascript:myJsFunc()">Link Text</a>

It gets around the need to return false. I don't like the # option because, as mentioned, it will take the user to the top of the page. If you have somewhere else to send the user if they don't have JavaScript enabled (which is rare where I work, but a very good idea), then Steve's proposed method works great.

<a href="javascriptlessDestination.html" onclick="myJSFunc(); return false;">Link text</a>

Lastly, you can use javascript:void(0) if you do not want anyone to go anywhere and if you don't want to call a JS function. Works great if you have an image you want a mouseover event to happen with, but there's not anything for the user to click on.

Will Read
The only downside with this (from memory, I may be wrong) is that IE doesn't consider an A to be an A if you don't have a href inside it. (So CSS rules won't work)
Benjol
+1  A: 

I believe you are presenting a false dichotomy. These are not the only two options.

I agree with Mr. D4V360 who suggested that, even though you are using the anchor tag, you do not truly have an anchor here. All you have is a special section of a document that should behave slightly different. A tag is far more appropriate.

Clever Human
A: 

If you use a link as a way to just execute some Javascript (instead of using a span like D4V360 greatly suggested), just do:

<a href="javascript:(function()%7Balert(%22test%22)%3B%7D)()%3B">test</a>

If you're using a link with onclick for navigation, don't use href="#" as the fallback when JS is off. It's usually annoying as hell when the user clicks on the link. Instead, provide the same link the onclick handler would provide if possible. If you can't do that, skip the onclick and just use a Javascript URI in the href.

Shadow2531
+14  A: 

For my two pennies I use javascript:void(0).

Three reasons. Encouraging the use of # amoungst a team of developers inevitably leads to some using the return value of the function called like this:-

function doSomething() {
    //some code
    return false;
}

but then they forget to use return doSomething() in the onclick and just use doSomething().

A second reason for avoiding # is that the final return false; will not execute if the called function throws an error. Hence the developers have to also remember to handle any error appropriately in the called function.

A third reason is that there are cases where the onclick event property is assigned dynamically. I prefer to be able to call a function or assign it dynamically without having to code the function specifically for one method of attachment or another. Hence my onclick (or on anythings) in HTML markup look like this:-

onclick="someFunc.call(this)"

OR

onclick="someFunc.apply(this, arguments)"

using javascript:void(0) avoids all of the above headaches and I haven't found any examples of a downside.

So if you're a lone developer then you can clearly make your own choice but if you work as a team you have to either state:-

use href="#", make sure onclick always contains return false; at the end, that any function called does not throw an error and if you attach a function dynamically to the onclick property make sure that as well as not throwing an error it returns false.

OR

use href="javascript:void(0)"

the second is clearly easier to communicated.

AnthonyWJones
A: 

Neither, unless the afore mentioned link is injected with javascript otherwise this is very bad practise as disccussed above. Just wanted to add my voice as this sort of technique is still common place and still wrong!

The problem with such black and white statements is that it doesn't take into account wide variety of uses HTML based technology. I don't see why its 'very bad' or 'wrong'. Can you elaborate?
AnthonyWJones
A: 

If you are using an <a> element, why don't you just use this?

<a href="javascript:myJSFunc();" />myLink</a>

Personally i'd attach an event handler with JavaScript later on instead (using attachEvent or addEventListener or maybe <put your favorite JS framework here > also).

Pablo Cabrera
+8  A: 

I agree with suggestions above stating that you should use regular URL in href attribute, then call some javascript function in onclick. The flaw is, that they automaticaly add return false after the call.

The problem with this approach is, that if the function will not work or if there will be any problem, the link will become unclickable. Onclick event will always return false, so the normal URL will not be called.

There's very simple solution. Let function return true if it works correctly. Then use the returned value to determine if the click should be cancelled or not:

JavaScript

function doSomething() {
    alert( 'you clicked on the link' );
    return true;
}

HTML

<a href="path/to/some/url" onclick="return !doSomething();">link text</a>


Note, that I negate the result of doSomething() function. If it works, it will return true, so it will be negated (false) and the path/to/some/url will not be called. If function will return false (e.g. browser doesn't support something used within the function or anything else goes wrong), it is negated to true and the path/to/some/url is called.

Fczbkk
Clever technique.
Gary Willoughby
+1  A: 

"return false" is somewhat archaic for event cancellation, and never was documented.

Ideally you should call event.preventDefault() according to the DOM 2 Events specification.

RJFalconer
But how widely is it supported? IE6?
Alexander Abramov
+1  A: 

I recommend using a <button> element instead, especially if the control is supposed to produce a change in the data. (Something like a POST.)

It's even better if you inject the elements unobtrusively, a type of progressive enhancement. (See this comment.)

phyzome
+1  A: 

Usually, you should always have a fall back link to make sure that clients with JavaScript disabled still has some functionality. This concept is called unobtrusive JavaScript. Example... Let's say you have the following search link:

<a href="search.php" id="searchLink">Search</a>

You can always do the following:

var link = document.getElementById('searchLink');

link.onclick = function() {
    try {
        // Do Stuff Here        
    } finally {
        return false;
    }
};

That way, people with javascript disabled are directed to search.php while your viewers with JavaScript view your enhanced functionality.

Andrew Moore
+6  A: 

Wont it be better to use jQuery

$(document).ready(function() {
    $("a").css("cursor", "pointer");
});

and omit both href="#" and href="javascript:void(0)"

The anchor tag markup will be like

`<a onclick="hello()">Hello</a>`

Simple Enough, right?

naveen
This is what I was going to say. If a link has a fallback url that makes sense, use that. Otherwise, just omit the href or use something more semantically appropriate than an <a>. If the only reason everyone is advocating including the href is to get the finger on hover, a simple "a { cursor: pointer; }" will do the trick.
Matt Kantor
May I say this is the option that SO decided to go with. Check the "flag" links, for instance.
mtyaka
That gives terrible accessibility. Try it in SO: you can't flag a post without using the mouse. The "link" and "edit" links are accessible by tabbing, but "flag" isn't.
Nicolás
+2  A: 

Just to pick up the point some of the other have mentioned.

It's much better to bind the event 'onload'a or $('document').ready{}; then to put JavaScript directly into the click event.

in the case the case that JavaScript isn't available I would use a href to the current URL, and perhaps an anchor to the position of the link. The page is still be usable for the people without JavaScript those who have won't notice any difference.

As i have it to hand here is some jQuery which might help:

var [functionName] = function() {
};

jQuery("[link id or other selector]").bind("click", [functionName]);
Matt Goddard
LowPro is really nice for unobtrusive JS if you have a lot of complex behaviors.
Matt Kantor
A: 

There's another question similar to this one here.

cowgod
A: 

Thanks Naveen -- that's all I needed!

+1  A: 

You can also write a hint in anchor like this:

<a href="javascript:void('open popup image')" onclick="return f()">...</a>

so the user will know what does this link.

A: 

I use the following

<a href="javascript:;" onclick="myJsFunc();">Link</a>

instead of

<a href="javascript:void(0)" onclick="myJsFunc();">Link</a>
se_pavel
+2  A: 

Definitely hash is better because javascript: pseudoscheme 1) pollutes history 2) instantiates new copy of engine 3) runs in global scope and doesnt respect event system. Of course "#" with onclick handler which prevents default action is [much] better. Moreover, link that has the sole purpose to run javascript is not really "a link" unless you are sending user to some sensible anchor on the page (just # will send to top) when something goes wrong. You can simply simulate look and feel of link with stylesheet and forget about href at all. More details on this - How Not to Use Links

Addition regarding cowgod's suggestion, particularly this: ...href="javascript_required.html" onclick="... This is good approach but it doesn't distinguish between "javascript disabled" and "onclick fails" scenarios.

+4  A: 

# is better than javascript:anything, but the following is even better:

HTML:

<a href="/gracefully/degrading/url/with/same/functionality.ext" class="some-selector">For great justice</a>

JavaScript:

$(function() {
    $(".some-selector").click(myJsFunc);
});

You should always strive for graceful degradation (in the event that the user doesn't have JavaScript enabled...and when it is with specs. and budget). Also, it is considered bad form to use JavaScript attributes and protocol directly in HTML.

Justin Johnson
A: 

In total agreement with the overall sentiment, use void(0) when you need it, and use a valid url when you need it. Using Mod Rewrite you can make urls that not only do what you want to do with javascript disabled, but also tell you exactly what its going to do.

<a href="./Readable/Text/URL/Pointing/To/Server-Side/Script" id="theLinkId">WhyClickHere</a>

On the server side you just have to parse the url & query string and do what thou wilt. If you are clever you can allow the server side script to respond to both ajax and standard requests differently. Allowing you to have concise centralized code that handles all the links on your page.

Mod ReWrite Tutorials

Pros

  • Shows up in status bar
  • Easily upgraded to Ajax via onclick handler in JS
  • Practically comments itself
  • Keeps your directories from becoming littered with single use html files

Cons

  • Should still use event.preventDefault() in JS
  • Fairly complex path handling and url parsing on the server side.

I am sure there are tons more cons out there. Feel free to discuss them.