557

I want to run a simple JavaScript function on a click without any redirection.

Is there any difference or benefit between putting the JavaScript call in the href attribute (like this):

<a href="javascript:my_function();window.print();">....</a>

vs. putting it in the onclick attribute (binding it to the onclick event)?

saw
  • 318
  • 2
  • 6
  • 13
SkunkSpinner
  • 11,429
  • 7
  • 40
  • 53
  • 7
    This question has been discussed before: http://stackoverflow.com/questions/245868/what-is-the-difference-between-the-different-methods-of-putting-javascript-in-an – SolutionYogi Jul 01 '09 at 19:07
  • 2
    And http://stackoverflow.com/questions/134845/href-for-javascript-links-or-javascriptvoid0 – Sampson Jul 01 '09 at 19:13

19 Answers19

1111

bad:

<a id="myLink" href="javascript:MyFunction();">link text</a>

good:

<a id="myLink" href="#" onclick="MyFunction();">link text</a>

better:

<a id="myLink" href="#" onclick="MyFunction();return false;">link text</a>

even better 1:

<a id="myLink" title="Click to do something"
 href="#" onclick="MyFunction();return false;">link text</a>

even better 2:

<a id="myLink" title="Click to do something"
 href="PleaseEnableJavascript.html" onclick="MyFunction();return false;">link text</a>

Why better? because return false will prevent browser from following the link

best:

Use jQuery or other similar framework to attach onclick handler by element's ID.

$('#myLink').click(function(){ MyFunction(); return false; });
Gray
  • 115,027
  • 24
  • 293
  • 354
demp
  • 12,665
  • 2
  • 23
  • 17
  • 27
    There would be another solution which would be the best where `href` is not set to `#` but to an actual link for the noJS browsers. – helly0d Nov 29 '12 at 02:45
  • 2
    it is not another solution but an extension to "even better" point. In this case, if the browser doesn't support JavaScript or it is switched off then the user will be brought to some warning \ explanation page. And if the browser supports JS then return false will prevent the browser from following the link. – demp Dec 12 '12 at 12:54
  • 7
    What if i tell you that ony the first (bad) one works the same (right) way in all browsers with middleclick. – Vloxxity Apr 24 '13 at 14:06
  • In the example it seems that best is an alternative to the above, however, best is the next step using one of the links above. Best can only work when a tag link was clicked – Timo Oct 20 '13 at 19:07
  • 2
    `javascript:void(0)` would not be better than `#` in your **even better 1** ? – Michel Ayres May 22 '14 at 13:25
  • 1
    btw, even better than `$('#myLink').click(function(){ MyFunction(); return false; });` you could add it to a `on` function, like: **`$(document).on('click', ''#myLink', function() { MyFunction(); return false; });`** – Michel Ayres May 22 '14 at 13:34
  • 1
    @Michel Ayres - that isn't necessarily better, just different. and his "best" isn't best at all, just average. Best would be to decouple event binding from the logic of execution. – vsync May 25 '14 at 20:45
  • @vsync - thanks! great to see the conversation going. Good point about decoupling. – demp Jun 07 '14 at 09:02
  • 1
    what if the links are dynamically generated with parameters? using a separate jquery block is not best practice in this case – Sentinel Jul 31 '14 at 15:02
  • If we use onClick, does that make it ADA Compliant? – Poulami Dec 16 '14 at 12:35
  • 19
    What is bad about ? – Kartick Vaddadi Jan 27 '15 at 12:43
  • 8
    Just my humble 5 cents: "the best" option would be to use buttons for clicks (onclick events?) and leave anchors with their href's to what their original design intention was in the first place: to be anchors for links to other pages. – nidalpres Jan 30 '15 at 22:08
  • 5
    The on click binding with javascript has one downside: Later when your are debugging some one else his form, it's really hard to find where and what kind of javascript is binding to that element. – Maarten Kieft Sep 17 '15 at 14:46
  • I found that $('#myLink').click(function(){ doesn't intercept the click when the user opts to open link in new tab. At least, that's what is happening in Firefox. – user442920 Jan 23 '16 at 15:34
  • 1
    Michel Ayres, you are correct. href="#" will force most browsers to search by id and therefore scroll to the top of the page. This is generally undesirable. – Anthony Mason Apr 17 '16 at 17:35
  • 3
    **Why**? if anybody give some detail explain or web link? thanks – dannyliu Apr 20 '16 at 05:57
  • What if I want to use a `bootstrap-confirmation` on my link. The `onclick` version wont work. – djack109 Nov 30 '16 at 17:55
  • 2
    I want to add to the **best** method and make it **better than the best**. Drop the whole `a` tag with the useless `href="#"` and apply the `onclick` handler directly on the content. If the content is a tag, you can just apply the `myLink` id on it. If the content is not a tag, surround a `span` tag on it and apply the `myLink` id to the `span`. Finally in CSS, add `cursor: pointer;`. This way, the link is very neat like a button and does not add an ugly `#` to the URL or show this ugly `#` on the link tooltip. – ADTC Dec 30 '16 at 12:23
  • 2
    Stoping the event at the beggining of the click should be prefered over return false since any crash in your javascript is going to trigger the href. Ironically the 'bad' option is the only safe one for this scenario. – Ziul Jan 27 '17 at 01:36
  • 1
    I'm an Android developer and I need to execute a deeplink to my application. in this case your 'bad' solution is my solution. I can't call my deeplink within a javascript function since this is blocked by chrome on Android. I need to use a href! – Allinone51 Feb 19 '17 at 10:29
  • 2
    Please downvote this answer into oblivion as it is a very bad practice. Linking to "#" can have disastrous results for things that depend on anchors or simply losing one's scroll position. – slothstronaut Mar 11 '17 at 07:51
  • 1
    using jQuery binding actually the worse, we will not realise if that HTML DOM is calling a function of not looking to javascript file. and using `#` also bad as it changed your HTML structure. – GusDeCooL Mar 14 '17 at 00:30
  • What is the difference between the good and the better example, mainly, what does the return false achieve? – Scorb Oct 14 '17 at 00:32
  • 11
    but, why bad ? why good ? why better ? why even better 1 ? why even better 2 ? why best ? if it works, it works. – Baim Wrong Apr 20 '18 at 02:23
  • href="#" would return the user to the top of the page. Where this is not desirable, I used link – David Robertson Mar 17 '22 at 11:32
309

Putting the onclick within the href would offend those who believe strongly in separation of content from behavior/action. The argument is that your html content should remain focused solely on content, not on presentation or behavior.

The typical path these days is to use a javascript library (eg. jquery) and create an event handler using that library. It would look something like:

$('a').click( function(e) {e.preventDefault(); /*your_code_here;*/ return false; } );
wilbbe01
  • 1,931
  • 1
  • 24
  • 38
Parand
  • 102,950
  • 48
  • 151
  • 186
  • 1
    Or mootools, prototype, dojo ... or plain on javascript, but that'd be a whole lot more code but worth the excercise. – Ryan Florence Jul 01 '09 at 19:10
  • 17
    If you don't have to do anything with the event object, plain javascript is pretty simple. Get the DOM node with obj = document.getElementById(), then set obj.onclick = foo – Matt Bridges Jul 01 '09 at 19:24
  • 1
  • 9
    But wasn't the question asking about the difference between putting the JS call inline in `href` versus inline in `onclick`? Assuming you were going to put it inline for some reason, which should you use? (In practice I would do what you've suggested, but you seem to have skipped over the difference between the two attributes.) – nnnnnn Sep 06 '17 at 02:35
  • 2
    The one time I would advocate for putting the function call inline vs. having an onclick event for the link is if you are dynamically creating links within the page that will all call the same function but may not have unique ids. I have a webform where the user can add and remove items and I put the onclick in the href of the links within the dynamically created divs so I can get a quicker start on processing the script instead of using something less specific like a relative id or class name. – MistyDawn Nov 15 '17 at 01:40
  • 1
    I really disagree with that "separation of content from behavior" idea. When you adhere to that, the connection between content and behavior is not obvious. So how do you know where the heck behavior is? You gotta search by id or class now which is a problem. There are often multiple return results - which one is the one you are looking for? You have to read through all the code to figure it out. It is very unproductive. Now it's bad to put function definitions in the content so there is such a thing as going too far. – Jason Cheng Jan 27 '21 at 16:09
  • The side effect of strong belief is separation of thoughts and reality. If one separates the content from action, he denies himself the concept of static links with dynamic resolution. – Jan Turoň Nov 23 '21 at 15:30
  • As somebody who believes strongly in separation of content from behavior / action, I generally find HTML / CSS offensive as a whole. So it's all good, haha. – Jason C May 30 '22 at 13:47
75

In terms of javascript, one difference is that the this keyword in the onclick handler will refer to the DOM element whose onclick attribute it is (in this case the <a> element), whereas this in the href attribute will refer to the window object.

In terms of presentation, if an href attribute is absent from a link (i.e. <a onclick="[...]">) then, by default, browsers will display the text cursor (and not the often-desired pointer cursor) since it is treating the <a> as an anchor, and not a link.

In terms of behavior, when specifying an action by navigation via href, the browser will typically support opening that href in a separate window using either a shortcut or context menu. This is not possible when specifying an action only via onclick.


However, if you're asking what is the best way to get dynamic action from the click of a DOM object, then attaching an event using javascript separate from the content of the document is the best way to go. You could do this in a number of ways. A common way is to use a javascript library like jQuery to bind an event:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<a id="link" href="http://example.com/action">link text</a>
<script type="text/javascript">
    $('a#link').click(function(){ /* ... action ... */ })
</script>
Adam
  • 1,744
  • 1
  • 14
  • 34
19

EDITOR WARNING: See the comments, the use of 'nohref' is incorrect in this answer.

I use

Click <a nohref style="cursor:pointer;color:blue;text-decoration:underline"
onClick="alert('Hello World')">HERE</a>

A long way around but it gets the job done. use an A style to simplify then it becomes:

<style> A {cursor:pointer;color:blue;text-decoration:underline; } </style> 
<a nohref onClick="alert('Hello World')">HERE</a>
Cameron
  • 2,903
  • 1
  • 30
  • 31
Clif Collins
  • 271
  • 2
  • 2
  • 11
    +1 Really great! :-) I had never heard about `nohref` attribute before. This is the most logical/elegant way to handle such javascript actions. This is compatible with FF12 and IE8. Therefore I will replace all my `href="JavaScript:void(0);"` by `nohref`. Thanks a lot. Cheers. – oHo May 09 '12 at 09:10
  • 7
    it's not supported by major browsers, why should we use this? http://www.w3schools.com/tags/att_area_nohref.asp – hetaoblog Jun 29 '12 at 06:40
  • 13
    `nohref` is a part of `area` tag, not `a`! Your example is the same as `HERE` – nZeus May 27 '15 at 09:52
  • 8
    Just another "don't do this warning". This is completely non-standard and bad advice. `nohref` doesn't exist on an `a` tag. – Colin 't Hart Sep 02 '19 at 10:40
17

The top answer is a very bad practice, one should never ever link to an empty hash as it can create problems down the road.

Best is to bind an event handler to the element as numerous other people have stated, however, <a href="javascript:doStuff();">do stuff</a> works perfectly in every modern browser, and I use it extensively when rendering templates to avoid having to rebind for each instance. In some cases, this approach offers better performance. YMMV

Another interesting tid-bit....

onclick & href have different behaviors when calling javascript directly.

onclick will pass this context correctly, whereas href won't, or in other words <a href="javascript:doStuff(this)">no context</a> won't work, whereas <a onclick="javascript:doStuff(this)">no context</a> will.

Yes, I omitted the href. While that doesn't follow the spec, it will work in all browsers, although, ideally it should include a href="javascript:void(0);" for good measure

slothstronaut
  • 921
  • 1
  • 13
  • 15
  • Thanks for this; hopefully it ends up higher on the list. Was struggling with those `#` problems. Btw, I notice that even if I assign the click handler with JS, the `href="javascript:void(0);"` still seems to be a good idea, since the link doesn't quite have the right UI if there's no `href` (at least, on Chrome, it loses the default mouse cursor and link coloring). – Jason C May 30 '22 at 13:50
13

the best way to do this is with:

<a href="#" onclick="someFunction(e)"></a>

The problem is that this WILL add a hash (#) to the end of the page's URL in the browser, thus requiring the user to click the back button twice to go to the page before yours. Considering this, you need to add some code to stop event propagation. Most javascript toolkits will already have a function for this. For example, the dojo toolkit uses

dojo.stopEvent(event);

to do so.

linusthe3rd
  • 3,455
  • 3
  • 28
  • 43
  • 11
    I would like to warn that if you use `href="#"` the browser will look for a named anchor tag and since it won't find it, then it'll make the window to scroll to the top of the page, something that might not be noticeable if you're already at the top. To avoid this behavior use: `href="javascript:;"` instead. – alonso.torres Nov 25 '11 at 16:04
  • 1
    @alonso.torres Good point, but that's why I mentioned the use of dojo.stopEvent() - it will stop event propagation/bubbling and the default behavior of clicking the anchor. – linusthe3rd Nov 26 '11 at 21:36
  • 7
    Instead of stopEvent, why not just returning false (onclick="someFunction(e);return false;") – stracktracer Jul 24 '13 at 18:46
11

In addition to all here, the href is shown on browser's status bar, and onclick not. I think it's not user friendly to show javascript code there.

Kamarey
  • 10,832
  • 7
  • 57
  • 70
9

This works

<a href="#" id="sampleApp" onclick="myFunction(); return false;">Click Here</a>
TitusMix
  • 101
  • 2
  • 9
  • 3
    Welcome to Stack Overflow! While this code snippet may solve the question, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, as this reduces the readability of both the code and the explanations! – Blue Feb 08 '18 at 08:56
8

Having javascript: in any attribute that isn't specifically for scripting is an outdated method of HTML. While technically it works, you're still assigning javascript properties to a non-script attribute, which isn't good practice. It can even fail on old browsers, or even some modern ones (a googled forum post seemd to indicate that Opera does not like 'javascript:' urls).

A better practice would be the second way, to put your javascript into the onclick attribute, which is ignored if no scripting functionality is available. Place a valid URL in the href field (commonly '#') for fallback for those who do not have javascript.

zombat
  • 92,731
  • 24
  • 156
  • 164
  • 1
    I don't see how there's any difference between a 'javascript:' href and a '#' href with an onclick attribute. Both are equally useless for browsers without JS enabled. – harto Jul 02 '09 at 02:40
  • 2
    harto, that's not actually correct. '#' is an indicator for a named link, it is not a javascript identifier. It is a valid URL, and does not require Javascript to be recognized. – zombat Jul 02 '09 at 06:13
8

it worked for me using this line of code:

<a id="LinkTest" title="Any Title"  href="#" onclick="Function(); return false; ">text</a>
6

First, having the url in href is best because it allows users to copy links, open in another tab, etc.

In some cases (e.g. sites with frequent HTML changes) it is not practical to bind links every time there is an update.

Typical Bind Method

Normal link:

<a href="https://www.google.com/">Google<a/>

And something like this for JS:

$("a").click(function (e) {
    e.preventDefault();
    var href = $(this).attr("href");
    window.open(href);
    return false;
});

The benefits of this method are clean separation of markup and behavior and doesn't have to repeat the function calls in every link.

No Bind Method

If you don't want to bind every time, however, you can use onclick and pass in the element and event, e.g.:

<a href="https://www.google.com/" onclick="return Handler(this, event);">Google</a>

And this for JS:

function Handler(self, e) {
    e.preventDefault();
    var href = $(self).attr("href");
    window.open(href);
    return false;
}

The benefit to this method is that you can load in new links (e.g. via AJAX) whenever you want without having to worry about binding every time.

jchavannes
  • 2,440
  • 1
  • 26
  • 15
5

Personally, I find putting javascript calls in the HREF tag annoying. I usually don't really pay attention to whether or not something is a javascript link or not, and often times want to open things in a new window. When I try doing this with one of these types of links, I get a blank page with nothing on it and javascript in my location bar. However, this is sidestepped a bit by using an onlick.

Peter
  • 421
  • 2
  • 8
5

The most upvoted answer is obsolete today

I would recommend the exact opposite, see step by step with reasons:

good:

<a id="myLink" href="javascript:MyFunction();">link text</a>

It depends, might be good, because crawlers follows href targets and if there is any meaningful content produced by MyFunction() (dynamic link), it is followed more likely than in the click event, which may have multiple or none listeners.

bad:

<a id="myLink" href="#" onclick="MyFunction();">link text</a>

# means meaningless link, crawlers are often interested only in first x links, so it can prevent them to follow some meaningful links later in the page.

worse:

<a id="myLink" href="#" onclick="MyFunction();return false;">link text</a>

Same as previous plus return false prevents following the link. If some other scripts want to add another listener and update the target (say to redirect via proxy), they can't without modifying the onclick (okay, it's just a minor setback as such use cases are rather theoretical).

worst:

Use jQuery or other similar framework to attach onclick handler by element's ID.

$('#myLink').click(function(){ MyFunction(); return false; });

jQuery is outdated in 2020+ and should not be used in new projects.

Events in href

The href attribute handler doesn't get the event object, so the handler doesn't implicitly see which link was the source. You can add it in onclick handler, which fires before the href is followed:

<a href="javascript:my_function(event2)" onclick="event2=event">
  JS based link
</a>

<script>
function my_function(e) {
  console.log(e.target); // the source of the click
  if(something) location.href = ...; // dynamic link
}
</script>
Jan Turoň
  • 31,451
  • 23
  • 125
  • 169
3

One more thing that I noticed when using "href" with javascript:

The script in "href" attribute won't be executed if the time difference between 2 clicks was quite short.

For example, try to run following example and double click (fast!) on each link. The first link will be executed only once. The second link will be executed twice.

<script>
function myFunc() {
    var s = 0;
    for (var i=0; i<100000; i++) {
        s+=i;
    }
    console.log(s);
}
</script>
<a href="javascript:myFunc()">href</a>
<a href="#" onclick="javascript:myFunc()">onclick</a>

Reproduced in Chrome (double click) and IE11 (with triple click). In Chrome if you click fast enough you can make 10 clicks and have only 1 function execution.

Firefox works ok.

kolobok
  • 3,835
  • 3
  • 38
  • 54
1
 <hr>
            <h3 class="form-signin-heading"><i class="icon-edit"></i> Register</h3>
            <button data-placement="top" id="signin_student" onclick="window.location='signup_student.php'" id="btn_student" name="login" class="btn btn-info" type="submit">Student</button>
            <div class="pull-right">
                <button data-placement="top" id="signin_teacher" onclick="window.location='guru/signup_teacher.php'" name="login" class="btn btn-info" type="submit">Teacher</button>
            </div>
        </div>
            <script type="text/javascript">
                $(document).ready(function(){
                $('#signin_student').tooltip('show'); $('#signin_student').tooltip('hide');
                });
            </script>   
            <script type="text/javascript">
                $(document).ready(function(){
                $('#signin_teacher').tooltip('show'); $('#signin_teacher').tooltip('hide');
                });
            </script>   
Andrew
  • 15
  • 1
  • 3
0

I experienced that the javascript: hrefs did not work when the page was embedded in Outlook's webpage feature where a mail folder is set to instead show an url

Christian
  • 2,903
  • 4
  • 31
  • 34
0
<a href="#" onclick="try{FUNCTION_YOU_WANT()}catch(e){}return false">click here</a>
  • Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation](https://meta.stackexchange.com/q/114762/9193372) would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please edit your answer to add some explanation, including the assumptions you’ve made. – Syscall Mar 24 '21 at 14:28
0

I cant belive that +13 years later, all of these answers are semantically incorrect! An anchor element <a>:

...with its href attribute, creates a hyperlink to web pages, files, email addresses, locations in the same page, or anything else a URL can address.

Content within each should indicate the link's destination. If the href attribute is present, pressing the enter key while focused on the element will activate it.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a

Therefore, using an href= for javascript is bad practice and poor web semantics. You should rather be using an onclick= event handler attribute on a button element, as:

The HTML element is an interactive element activated by a user with a mouse, keyboard, finger, voice command, or other assistive technology. Once activated, it then performs a programmable action, such as submitting a form or opening a dialog.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button

and the event handler onclick=:

All event handler attributes accept a string. The string will be used to synthesize a JavaScript function like function name(/args/) {body}, where name is the attribute's name, and body is the attribute's value.

https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes#event_handler_attributes

As you are not navigating to a URL or a Link destination, but rather triggering a Javascript function the correct way to do this is to use onclick. And if you need the style of an anchor tag on a button, just use CSS.

The bottom line is: just because you can do it doesn't mean you should.

grantmx
  • 106
  • 9
-1

This works as well

<a (click)='myFunc()'>Click Here </a>

(onclick) did not work for me in an Angular project with bootstrap.

Mohitn29
  • 21
  • 6