views:

403

answers:

11

I want to make a link call a Javascript function through the onclick event and not do anything else (follow the link). What is the best way to do that? I usually do this:

<a href="#" onclick="foo()">Click</a>

But I'm not sure that is the best way and in this case it is navigating to page.html# which isn't good for what I'm doing.

A: 

Does it NEED to be a link? Or, could you use:

<div onclick="foo()">Click</div>

Adjust the visuals to taste using CSS... :)

BoltBait
Exactly what I would suggest. Because if you're taking away the semantic meaning and behavior away from an anchor, then why are you using an anchor in the first place?
Kon
Be careful with that: div is block-level. a is inline.
Joel Coehoorn
Yes, beg your pardon, use SPAN instead of DIV.
BoltBait
Divs are not keyboard focusable - be careful not to make your page depend on the use of a pointing device.
David Dorward
plus, it takes away the ability for your page to downgrade gracefully. Look at any of the up-voted answers for better ways to do this.
nickf
A: 
<a href="javascript: foo()" >Click</a>
chris
Why is this getting voted down? I don't care about the points, but I'd like to know what's wrong.
chris
it's just not the best answer. See Andrew Moore's answer. http://stackoverflow.com/questions/184858#184916
nickf
+6  A: 

Just make sure to return false from your onlick handler. E.g. foo() should be defined as:

function foo() {
  // ... do stuff
  return false;
}

Someone pointed out in the comments that you may need to change your HTML slightly for that to work:

<a href="#" onclick="return foo()">Click</a>

Or just put it in the HTML:

<a href="#" onclick="foo(); return false;">Click</a>
Avdi
If you do this, I think you need to change the link's onclick to "return Foo();"
Lou Franco
@Lou I think you might be right.
Avdi
Is the purpose of the return false to prevent the page from trying to navigate to the non-existent anchor?
John Rudy
Yes, returning false tells the browser not to follow the link after all. You can use this for validation too, return true if everything is ok and false if not.
Joe Skora
If the JavaScript fails, the alternative content is a link to the top of the page. This rarely makes sense.
David Dorward
A: 

return false after calling foo()

Lou Franco
A: 

If you include

return false;

from the onclick event, then the page won't load at all. For example:

<a href="#" onclick="foo();return false;">Click</a>

Or in the function itself:

function foo() {
  // other stuff
  return false;
}
Rob Drimmie
A: 

Set the href attribute to execute the javascript. Like this:

<a href="javascript:foo()">Click</a>

That way all of your a:hover CSS styles work as expected.

Matt Brunell
+2  A: 

The problem with href="#" is that it will throw the browser to the top of the page. You can do:

<a href="javascript:foo()">clicky</a>

Though more people are recommending against doing that (separation of layers). A better way, using Prototype (just as easy in JQuery, et al):

<a id="foo" href="#">clicky</a>

$('foo').observe('click', function(evt) { 
  foo();
  evt.stop(); // keeps it from navigating to the href url
});
swilliams
Hang on a sec, the return false doesn't have the behavior I was expecting... Looking it up now.
swilliams
Ok, fixed it :).
swilliams
+3  A: 

First, there are two ways to setup the href - you can either do as you have stated above with the href referencing a '#', or you may set the href to reference "javascript:;"

Secondly, I always recommend keeping the JavaScript in an external file and then managing the event handler there. Assuming you'd like to set this up whenever the page loads, you could do something like this:

window.onload = {
    var myLink = document.getElementById('myLinkID');
    myLink.onclick = function(evt) {
        var evt = (evt) ? evt : ((event) ? event : null); // for cross-browser issues
        evt.preventDefault();
        evt.stopPropagation();
        foo();
    }
}
Tom
What happens with event.preventDefault or null.preventDefault?
eyelidlessness
@eyelidlessness - I could be misunderstanding your question, but the ternary operator above makes sure that you get a reference to an existing object so evt.preventDefault() will work across the major browsers. At any rate, it will cancel the event without stopping propagation of the event.
Tom
+15  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.

Edit: As nickf pointed out in comment #2, a try and catch will prevent the link to follow if there is an error in your handler.

Andrew Moore
Upped. If you're really looking for the BEST solution, this is it. You should decouple your HTML (presentation) from your JavaScript (logic). Start off with an ordinary link and then add the click event handler afterwards.
Ates Goral
+1. This is the right way to do it. The only thing I'd add is that if there's a JS error in your onclick handler, it won't get to return false, and so the link will be followed. To avoid that, wrap your whole function in a try block: "try { // do stuff here } finally { return false; }"
nickf
If there is an error in the handler, then often you would want the link to be followed. "Do it in JS or Fall back to server" is better then "Do it in JS or Have an error or Fall back to server"
David Dorward
Dorward, the problem with "Do it in JS or Fall back to server" is it makes debugging hard.
Andrew Moore
A: 

A lot of confusion is around the use of a-tags because they cross-browser support the :hover pseudo-css-selector ...

Therefore it's often obvious to use an a-tag, as it would render differently according to different stages of mouse-hover ...

Some would claim that the functionality built into the :hover pseudo-tag shouldn't be available at all, as the W3C intention is to separate content, visual presentation and functionality in the three parts of dynamic html; html, css and javascript.

But for now we're stuck with it, and for the time being it is functional to use a-tags in a lot of ways, as they accomplish tasks in a simple way, and it is right-forward cross-browser !-)

But that means that you sometimes have to disable the default behavior of those link-tags, and that means that you have to make the onclick-event return false, when it doesn't make sense to change the contents of the current document ...

However very good examples of using the dismissing of default behavior can be made, an example could be to provide a popup with certain properties even if the user has disabled the use of javascript:

<a href="http://en.wikipedia.org/wiki/Css" target="_blank" onclick="window.open(this.href,'_blank','width=600,height=450,status=no');return false;">Show wikipedia css</a>
roenving
A: 

Beware just using

<a href="#">Click</a>

as it can cause an obnoxious IE6 problem.

I always recommend using an anchor that points to nothing. I like to use this

<a href="#MAGIC">Click</a>

because it makes me laugh.

Tivac